using demo.ServiceRef;
using demo.Tool;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Globalization;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using ZXing.QrCode.Internal;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;

namespace demo
{
    public partial class WinChargeNew : Form
    {
        private static ServerSQL.operateSoapClient sqlServer;
        private Thread threadQRBarCodePay;
        private string _qrCode;
        string IsSelect = "";
        OpaqueCommand cmd = new OpaqueCommand();
        private Thread threadQueryPatient;
        private static ServiceRef.QueryPatientInfoOut patinfo;
        private static Dictionary<string, ServiceRef.QueryToPayRecipeDetailInfoOut[]> PayDetail;
        private static ServiceRef.BaseListOfQueryToPayRecipeInfoOuto4BIDE2W originalBillitemArray;
        //public List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem> payDetailList = new List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem>();
        string queryDate = "";
        string EndDate = "";
        UesrModel userData;
        
        // 定时器相关变量
        private System.Windows.Forms.Timer timerPatientQuery;
        private System.Windows.Forms.Timer timerDataRefresh;
        
        // 折叠功能相关变量
        private bool isLocalDataCollapsed = false;
        private int originalDgvMasterY;
        private int originalDgvDetailY;
        private int originalCbShowDetailY;
        private int originalLblLoadingStatusY;
        private Size originalDgvDetailSize;
        
        // QRBarCodePayRequest2函数所需变量
        private int QRBarCodePayRes = -999;
        private string QRBarCodePayMsg = "";
        private string DMFOutTradeNo = "";
        private QRBarPayOutput outputQRBarPayOutput;
        // 定时器防重入控制标记
        private volatile bool isPatientQueryRunning = false;
        private volatile bool isDataRefreshRunning = false;
        // UI 同步上下文字段
        private SynchronizationContext uiContext;
        // 输入法与字符大小写管理相关字段（仅针对tb_qrcode）
        private InputLanguage previousInputLanguage;
        private bool previousImeOpen;
        private uint previousImeConversion;
        private uint previousImeSentence;
        private CharacterCasing previousCharacterCasing;
        private bool hasSavedImeState = false;
        // 扫码回车防重与去抖
        private volatile bool isQrScanProcessing = false;
        private DateTime lastEnterTime = DateTime.MinValue;
        private readonly TimeSpan enterDebounceInterval = TimeSpan.FromMilliseconds(300);
        // 支付成功居中提示相关字段
        private Label lblTransientMessage;
    private System.Windows.Forms.Timer transientMsgTimer;
    private int transientMsgTicksRemaining;
    // BT_CARD 事件绑定状态，避免重复绑定
    private bool referralCardBtnHooked = false;
    
    private class DeptOption
    {
        public string DeptName { get; }
        public string OrgCode { get; }
        public DeptOption(string deptName, string orgCode)
        {
            DeptName = deptName ?? string.Empty;
            OrgCode = orgCode ?? string.Empty;
        }
        public override string ToString()
        {
            return DeptName;
        }
    }
        public WinChargeNew()
        {
            InitializeComponent();
            // 用户关闭本窗体时退出整个程序
            this.FormClosed += new FormClosedEventHandler(WinChargeNew_FormClosed);
        }
        /// <summary>
        /// 安全地在UI线程执行委托，基于SynchronizationContext异步调度，避免阻塞后台线程
        /// </summary>
        private void SafeBeginInvoke(Action action)
        {
            try
            {
                if (this.IsDisposed || !this.IsHandleCreated) return;

                var ctx = uiContext ?? SynchronizationContext.Current;
                if (ctx != null)
                {
                    ctx.Post(_ =>
                    {
                        try
                        {
                            if (this.IsDisposed || !this.IsHandleCreated) return;
                            action();
                        }
                        catch (Exception ex)
                        {
                            operateLog.WriteLog($"UI更新执行失败: {ex.Message}");
                        }
                    }, null);
                }
                else
                {
                    // 回退到控件BeginInvoke以确保兼容
                    this.BeginInvoke(new MethodInvoker(() =>
                    {
                        if (this.IsDisposed || !this.IsHandleCreated) return;
                        action();
                    }));
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"UI更新调度失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 安全设置剪贴板文本：在STA后台线程中尝试，快速失败并记录日志，避免阻塞UI线程
        /// </summary>
        /// <param name="text">要复制到剪贴板的文本</param>
        /// <param name="maxRetries">最大重试次数</param>
        /// <param name="timeoutMs">每次尝试的超时时间（毫秒）</param>
        private void SafeSetClipboardText(string text, int maxRetries = 3, int timeoutMs = 200)
        {
            if (string.IsNullOrEmpty(text)) return;
            for (int attempt = 1; attempt <= maxRetries; attempt++)
            {
                bool success = false;
                Exception lastEx = null;

                Thread t = new Thread(() =>
                {
                    try
                    {
                        Clipboard.SetDataObject(text, true);
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        lastEx = ex;
                    }
                });
                t.IsBackground = true;
                try { t.SetApartmentState(ApartmentState.STA); } catch { }
                t.Start();

                if (!t.Join(timeoutMs))
                {
                    try { operateLog.WriteLog($"剪贴板设置超时（{timeoutMs}ms），第{attempt}次重试"); } catch { }
                    continue;
                }

                if (success) return;

                try { operateLog.WriteLog($"剪贴板设置失败（第{attempt}次）：{lastEx?.Message}"); } catch { }
                Thread.Sleep(50);
            }
            try { operateLog.WriteLog("剪贴板设置最终失败，跳过复制以不中断流程"); } catch { }
        }

        /// <summary>
        /// 初始化居中红色动态提示控件与定时器
        /// </summary>
        private void InitTransientMessageLabel()
        {
            try
            {
                if (lblTransientMessage == null)
                {
                    lblTransientMessage = new Label();
                    lblTransientMessage.AutoSize = false;
                    lblTransientMessage.Text = "";
                    lblTransientMessage.Visible = false;
                    lblTransientMessage.BackColor = Color.Transparent;
                    lblTransientMessage.ForeColor = Color.Red;
                    lblTransientMessage.Font = new Font(this.Font.FontFamily, 20, FontStyle.Bold);
                    lblTransientMessage.TextAlign = ContentAlignment.MiddleCenter;
                    lblTransientMessage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
                    // 初始尺寸与位置（显示时会重新定位居中）
                    lblTransientMessage.Size = new Size(this.ClientSize.Width, 40);
                    lblTransientMessage.Location = new Point(0, (this.ClientSize.Height - lblTransientMessage.Height) / 2);
                    this.Controls.Add(lblTransientMessage);
                }

                if (transientMsgTimer == null)
                {
                    transientMsgTimer = new System.Windows.Forms.Timer();
                    transientMsgTimer.Interval = 200; // 200ms闪烁，3秒约15次
                    transientMsgTimer.Tick += TransientMsgTimer_Tick;
                }
            }
            catch (Exception ex)
            {
                try { operateLog.WriteLog($"初始化居中提示控件失败: {ex.Message}"); } catch { }
            }
        }

        /// <summary>
        /// 显示居中红色动态提示文本，指定显示毫秒数
        /// </summary>
        private void ShowTransientCenterMessage(string message, int durationMs = 3000)
        {
            try
            {
                InitTransientMessageLabel();
                if (lblTransientMessage == null || transientMsgTimer == null) return;

                // 重新定位到窗口中间并铺满宽度
                lblTransientMessage.Size = new Size(this.ClientSize.Width, 40);
                lblTransientMessage.Location = new Point(0, (this.ClientSize.Height - lblTransientMessage.Height) / 2);

                lblTransientMessage.Text = message ?? string.Empty;
                lblTransientMessage.ForeColor = Color.Red;
                lblTransientMessage.Visible = true;
                lblTransientMessage.BringToFront();

                transientMsgTicksRemaining = Math.Max(1, durationMs / transientMsgTimer.Interval);
                transientMsgTimer.Enabled = true;
            }
            catch (Exception ex)
            {
                try { operateLog.WriteLog($"显示居中提示失败: {ex.Message}"); } catch { }
            }
        }

        /// <summary>
        /// 居中提示定时器：闪烁红色并在时间到后隐藏
        /// </summary>
        private void TransientMsgTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                if (lblTransientMessage == null)
                {
                    transientMsgTimer.Enabled = false;
                    return;
                }

                // 简单闪烁效果
                lblTransientMessage.ForeColor = (lblTransientMessage.ForeColor == Color.Red) ? Color.DarkRed : Color.Red;

                transientMsgTicksRemaining--;
                if (transientMsgTicksRemaining <= 0)
                {
                    transientMsgTimer.Enabled = false;
                    lblTransientMessage.Visible = false;
                    lblTransientMessage.ForeColor = Color.Red;
                }
            }
            catch { transientMsgTimer.Enabled = false; }
        }

        /// <summary>
        /// 以统一方式启动患者查询线程。
        /// </summary>
        /// <param name="qrCode">二维码/条码字符串</param>
        /// <param name="disableInput">是否禁用输入控件以避免重复触发</param>
        private void StartPatientQueryWithQr(string qrCode, bool disableInput)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(qrCode)) return;

                // 若当前正在处理扫码，避免并发重入
                if (isQrScanProcessing)
                {
                    try { operateLog.WriteLog("跳过查询：正在处理上一次扫码"); } catch { }
                    return;
                }

                if (disableInput && tb_qrcode != null && !tb_qrcode.IsDisposed)
                {
                    tb_qrcode.Enabled = false;
                }

                // 查询前统一清理变量与界面数据，确保显示一致性
                try
                {
                    textBoxPayAmount.Text = "";
                    dgv_master.Rows.Clear();
                    dgv_detail.Rows.Clear();
                    patinfo = null;
                    PayDetail = null;
                    payDetailList = null;
                    lblPatientNameValue.Text = "";
                    lblPatientSexValue.Text = "";
                    lblPatientAgeValue.Text = "";
                    lblBalanceValue.Text = "0.00";
                    panelPatientInfo.Visible = false;
                }
                catch { }

                // 设置扫码处理中标记，防止重入；在线程结束处释放
                isQrScanProcessing = true;

                threadQueryPatient = new Thread(new ParameterizedThreadStart(DoWork))
                {
                    IsBackground = true
                };
                threadQueryPatient.Start(qrCode);
            }
            catch (Exception ex)
            {
                try { operateLog.WriteLog($"启动患者查询线程失败: {ex.Message}"); } catch { }
            }
        }
        
        /// <summary>
        /// 窗体加载事件处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WinCharge_Load(object sender, EventArgs e)
        {
            // 显示本机IP地址
            DisplayIPAddress();
            // 捕获Windows Forms同步上下文，用于统一的异步UI更新
            uiContext = SynchronizationContext.Current;
            // tb_qrcode获得/失去焦点时管理输入法与字符大小写
            try
            {
                if (tb_qrcode != null)
                {
                    tb_qrcode.Enter += tb_qrcode_Enter;
                    tb_qrcode.Leave += tb_qrcode_Leave;
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"注册tb_qrcode焦点事件失败: {ex.Message}");
            }
            
            // 保存dgv_master、dgv_detail、CB_SHOWDETAIL和lblLoadingStatus的原始位置和尺寸，用于折叠功能（当前仅记录以消除未使用警告）
            originalDgvMasterY = dgv_master.Location.Y;        // 当前位置: Y = 372
            originalDgvDetailY = dgv_detail.Location.Y;        // 当前位置: Y = 598
            originalCbShowDetailY = CB_SHOWDETAIL.Location.Y;  // 当前位置: Y = 573
            originalLblLoadingStatusY = lblLoadingStatus.Location.Y; // 当前位置: Y = 409
            originalDgvDetailSize = dgv_detail.Size;           // 当前尺寸: (822, 214)
            
            operateLog.WriteLog($"折叠功能初始化 - 原始位置: dgv_master.Y={originalDgvMasterY}, dgv_detail.Y={originalDgvDetailY}, CB_SHOWDETAIL.Y={originalCbShowDetailY}, lblLoadingStatus.Y={originalLblLoadingStatusY}, isLocalDataCollapsed={isLocalDataCollapsed}");
            // 初始化支付成功居中提示
            InitTransientMessageLabel();
            // 绑定 BT_CARD 点击事件以打开转介卡处理窗体（若按钮存在）
            try
            {
                if (!referralCardBtnHooked)
                {
                    var btnCard = this.Controls.Find("BT_CARD", true).FirstOrDefault() as System.Windows.Forms.Button;
                    if (btnCard != null)
                    {
                        referralCardBtnHooked = true;
                        btnCard.Click += (s, ev) =>
                        {
                            try
                            {
                                if (userData == null)
                                {
                                    MessageBox.Show("当前用户信息不可用，无法打开转介卡处理窗体", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    return;
                                }
                                var form = new ReferralCardForm(userData);
                                form.StartPosition = FormStartPosition.CenterParent;
                                form.ShowDialog(this);
                            }
                            catch (Exception ex)
                            {
                                try { operateLog.WriteLog($"打开转介卡处理窗体失败: {ex.Message}"); } catch { }
                            }
                        };
                    }
                }
            }
            catch { }
            try { if (btnToggleLocalData != null) btnToggleLocalData.Visible = false; } catch {}
        }

        /// <summary>
        /// tb_qrcode获取焦点：切换为英文半角并强制小写，同时保存原状态
        /// </summary>
        private void tb_qrcode_Enter(object sender, EventArgs e)
        {
            try
            {
                if (this.IsDisposed || !tb_qrcode.IsHandleCreated) return;
                // 保存原输入语言、IME状态与字符大小写
                previousInputLanguage = InputLanguage.CurrentInputLanguage;
                previousCharacterCasing = tb_qrcode.CharacterCasing;
                hasSavedImeState = ImeHelper.TryGetImeStatus(tb_qrcode.Handle, out previousImeOpen, out previousImeConversion, out previousImeSentence);

                // 强制该文本框为小写（不影响系统其他程序）
                tb_qrcode.CharacterCasing = CharacterCasing.Lower;

                // 优先切到已安装的英文输入法（若存在）
                var engLang = InputLanguage.InstalledInputLanguages
                    .Cast<InputLanguage>()
                    .FirstOrDefault(l => l.Culture.TwoLetterISOLanguageName == "en");
                if (engLang != null)
                {
                    InputLanguage.CurrentInputLanguage = engLang;
                }

                // 设置IME为半角英数
                ImeHelper.TrySetHalfWidthEnglish(tb_qrcode.Handle);
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"tb_qrcode_Enter 设置输入法失败: {ex.Message}");
            }
        }

        /// <summary>
        /// tb_qrcode失去焦点：恢复原输入法、IME状态与字符大小写
        /// </summary>
        private void tb_qrcode_Leave(object sender, EventArgs e)
        {
            try
            {
                // 恢复字符大小写设置
                tb_qrcode.CharacterCasing = previousCharacterCasing;

                // 恢复IME状态
                if (hasSavedImeState)
                {
                    ImeHelper.TryRestoreImeStatus(tb_qrcode.Handle, previousImeOpen, previousImeConversion, previousImeSentence);
                    hasSavedImeState = false;
                }

                // 恢复原输入语言
                if (previousInputLanguage != null)
                {
                    InputLanguage.CurrentInputLanguage = previousInputLanguage;
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"tb_qrcode_Leave 恢复输入法失败: {ex.Message}");
            }
        }
        public WinChargeNew(UesrModel userInfo)
        {
            InitializeComponent();
            userData = userInfo;
            var deptInfo = UserLoginManager.GetUserDeptInfo(userData.user_id);
            string deptDisplay = string.IsNullOrEmpty(deptInfo?.DeptName) ? string.Empty : ("   科室: " + deptInfo.DeptName + (string.IsNullOrEmpty(deptInfo.OrgCode) ? string.Empty : (" (" + deptInfo.OrgCode + ")")));
            this.Text = "柳州市妇幼诊间支付系统 - 版本 V" + Assembly.GetEntryAssembly().GetName().Version.ToString() + "   当前用户: " + userData.user_name + "   用户账号: " + userData.user_id + deptDisplay;
            queryDate = getNowDateTime().ToString("yyyy-MM-dd");
            EndDate = getNowDateTime().ToString("yyyy-MM-dd");
            sqlServer = new ServerSQL.operateSoapClient();
            IsSelect = ConfigurationManager.AppSettings["IsSelect"].ToString();
            setCmd();
            InitializeDataGridView();
            // 初始化本地数据
            LoadLocalData();
            // 加载医生患者记录数据
            LoadDoctorPatientRecords();
            // 初始化定时器
            InitializeTimers();
            // 初始化科室下拉（底部工具栏）
            InitDeptToolStrip();
            // 注意：DisplayIPAddress将在Form_Load事件中调用，确保窗体完全加载后再执行
            // 用户关闭本窗体时退出整个程序
            this.FormClosed += new FormClosedEventHandler(WinChargeNew_FormClosed);
        }

        private System.Windows.Forms.ToolStrip deptToolStrip;
        private System.Windows.Forms.ToolStripLabel lblDeptCaption;
        private System.Windows.Forms.ToolStripComboBox cboDeptSwitcherStrip;

        private void InitDeptToolStrip()
        {
            try
            {
                // 查询医生科室权限列表
                var resp = PatientDataService.QueryDoctorOutpDeptPermissions(userData.user_id);
                var items = resp?.Data;
                if (items == null || items.Count == 0)
                {
                    return; // 无权限数据则不显示工具栏
                }
                // 工具栏
                deptToolStrip = new System.Windows.Forms.ToolStrip();
                deptToolStrip.Dock = DockStyle.Bottom;
                deptToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
                deptToolStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
                deptToolStrip.AutoSize = false;
                deptToolStrip.Height = 32;

                lblDeptCaption = new System.Windows.Forms.ToolStripLabel("科室:");
                cboDeptSwitcherStrip = new System.Windows.Forms.ToolStripComboBox();
                cboDeptSwitcherStrip.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
                cboDeptSwitcherStrip.AutoSize = false;
                cboDeptSwitcherStrip.Width = 240;

                foreach (var it in items)
                {
                    cboDeptSwitcherStrip.Items.Add(new DeptOption(it.DeptName, it.OrgCode));
                }

                // 选择当前缓存的科室（若存在且有效）
                var deptInfo = UserLoginManager.GetUserDeptInfo(userData.user_id);
                if (!string.IsNullOrWhiteSpace(deptInfo?.DeptName))
                {
                    for (int i = 0; i < cboDeptSwitcherStrip.Items.Count; i++)
                    {
                        var opt = cboDeptSwitcherStrip.Items[i] as DeptOption;
                        if (opt != null && (string.Equals(opt.OrgCode, deptInfo.OrgCode, StringComparison.OrdinalIgnoreCase)
                                            || string.Equals(opt.DeptName, deptInfo.DeptName, StringComparison.OrdinalIgnoreCase)))
                        {
                            cboDeptSwitcherStrip.SelectedIndex = i;
                            break;
                        }
                    }
                }

                cboDeptSwitcherStrip.SelectedIndexChanged += (s, e) =>
                {
                    var opt = cboDeptSwitcherStrip.SelectedItem as DeptOption;
                    if (opt == null) return;
                    // 保存所选科室
                    UserLoginManager.SetUserDeptInfo(userData.user_id, opt.DeptName, opt.OrgCode);
                    // 更新标题显示
                    UpdateTitleWithDept(opt.DeptName, opt.OrgCode);
                };

                deptToolStrip.Items.Add(lblDeptCaption);
                deptToolStrip.Items.Add(cboDeptSwitcherStrip);
                this.Controls.Add(deptToolStrip);
                deptToolStrip.BringToFront();
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"初始化科室工具栏失败: {ex.Message}");
            }
        }

        private void UpdateTitleWithDept(string deptName, string orgCode)
        {
            try
            {
                string deptDisplay = string.IsNullOrEmpty(deptName) ? string.Empty : ("   科室: " + deptName + (string.IsNullOrEmpty(orgCode) ? string.Empty : (" (" + orgCode + ")")));
                this.Text = "柳州市妇幼诊间支付系统 - 版本 V" + Assembly.GetEntryAssembly().GetName().Version.ToString()
                           + "   当前用户: " + userData.user_name
                           + "   用户账号: " + userData.user_id
                           + deptDisplay;
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"更新标题失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 新版本主窗体关闭时退出整个程序。
        /// </summary>
        private void WinChargeNew_FormClosed(object sender, FormClosedEventArgs e)
        {
            try { StopTimers(); } catch { }
            Application.Exit();
        }

        //private void tb_qrcode_KeyPress(object sender, KeyPressEventArgs e)
        //{
            
                     
        //}

        private void tb_qrcode_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                // 去抖与防重入：部分扫码枪会发送连续两个回车（CRLF或双Enter）
                
                var now = DateTime.Now;
                if (now - lastEnterTime < enterDebounceInterval || isQrScanProcessing)
                {
                    e.SuppressKeyPress = true;
                    return;
                }
                lastEnterTime = now;

                //MessageBox.Show(tb_qrcode.Text);
                try
                {
                    // 清空支付金额输入框
                    textBoxPayAmount.Text = "";
                    // 清理扫码附带的CR/LF，确保后续校验与逻辑稳定
                    if (tb_qrcode.Text != null)
                    {
                        tb_qrcode.Text = tb_qrcode.Text.Replace("\r", string.Empty).Replace("\n", string.Empty).Trim();
                    }
                    
                    if (Regex.IsMatch(tb_qrcode.Text, @"[\uFF00-\uFFEF]"))
                    {
                        MessageBox.Show("输入包含全角符号，请重新输入！", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        // 清空输入框
                        tb_qrcode.Text = "";
                    }
                    else if (Regex.IsMatch(tb_qrcode.Text, @"[A-Z]"))
                    {
                        MessageBox.Show("输入包含大写字母，只允许输入小写字母，请重新输入！", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        // 清空输入框
                        tb_qrcode.Text = "";
                    }
                    else
                    {
                        SafeSetClipboardText(tb_qrcode.Text);
                        _qrCode = tb_qrcode.Text;
                        tb_qrcode.SelectAll();
                        dgv_master.Rows.Clear();
                        dgv_detail.Rows.Clear();
                        patinfo = null;
                        PayDetail = null; // 清空PayDetail数据
                        payDetailList = null; // 清空payDetailList数据
                        // 清空病人基本信息显示
                        lblPatientNameValue.Text = "";
                        lblPatientSexValue.Text = "";
                        lblPatientAgeValue.Text = "";
                        lblBalanceValue.Text = "0.00";
                        panelPatientInfo.Visible = false;
                        //operateLog.WriteLog("已清空dgv_master、dgv_detail控件数据和病人基本信息显示");
                        if (_qrCode.IndexOf("|") > 0 || _qrCode.IndexOf("=") > 0 || _qrCode.IndexOf("772:") == 0)  //;81293687|82665666?
                        {
                            StartPatientQueryWithQr(_qrCode, true);
                        }
                        else
                        {
                            MessageBox.Show("该类型卡号暂不支持充值！");
                            tb_qrcode.Text = "";
                            tb_qrcode.Focus();

                        }
                        //this.button2_Click(sender, e);
                    }
                }
                catch (Exception ex)
                {
                    try { operateLog.WriteLog("tb_qrcode_KeyDown 异常：" + ex.ToString()); } catch { }
                    MessageBox.Show("查询错误!", ex.ToString());
                }
                //_password = this.Text;
                finally { }
            }
        }

        private void DoWork(object obj)
        {
            try
            {
                string str = obj as string;
                //operateLog.WriteLog("执行查询患者信息开始");
                //operateLog.WriteLog("操作员ID：" + userData.user_id);
                //operateLog.WriteLog("操作员姓名：" + userData.user_name);
                //operateLog.WriteLog("输入卡号：" + str);
                patinfo = new QueryPatientInfoOut();
                PayDetail = new Dictionary<string, QueryToPayRecipeDetailInfoOut[]>(); // 清空PayDetail数据
                payDetailList = new List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem>(); // 清空payDetailList数据
                //return;
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                ServiceRef.QueryPatientInfoIn input = new ServiceRef.QueryPatientInfoIn();
                input.QueryType = "1";
                input.CardNO = str; //"772:905dd6b8-8c6d-4383-aab7-deb2ac08dff7:1";//
                input.CardName = "";
                input.CardTypeID = "1";
                if (str.Length > 15)
                    input.CardTypeID = "3";
                if (str.Length > 18)
                    input.CardTypeID = "4";
                input.TerminalCode = "001";
                patinfo = clientService.QueryPatientInfoCommon(input);
                //operateLog.WriteLog("执行查询患者信息结束");
                //operateLog.WriteLog("执行查询患者信息出参：" + patinfo.CardNO + patinfo.PatientName);
                
                // 记录DoWork结果的JSON日志（如果启用）
                //LogDoWorkResultToJson(str, patinfo, PayDetail, payDetailList);
                
                // 查询完成后更新UI显示患者信息
                if (this.Created)
                {
                    SafeBeginInvoke(UpdatePatientInfo);
                }
            }
            catch (Exception ex)
            {
                //operateLog.WriteLog("查询患者信息异常：" + ex.Message);
                if (this.Created)
                {
                    SafeBeginInvoke(() => {
                        MessageBox.Show("查询患者信息失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    });
                }
            }
            finally
            {
                // 查询线程结束，允许下一次扫码回车
                isQrScanProcessing = false;
                // 恢复扫码输入框可用状态
                SafeBeginInvoke(() =>
                {
                    if (tb_qrcode != null && !tb_qrcode.IsDisposed)
                    {
                        tb_qrcode.Enabled = true;
                        tb_qrcode.Focus();
                        tb_qrcode.SelectAll();
                    }
                });
            }
        }

        #region 查询患者待缴费信息

        /// <summary>
        /// 将查询到的待缴费数据写入本地JSON文件
        /// </summary>
        /// <param name="billitemArray">待缴费数据数组</param>
        /// <param name="patientInfo">患者信息</param>
        private void SaveBillDataToJson(ServiceRef.BaseListOfQueryToPayRecipeInfoOuto4BIDE2W billitemArray, ServiceRef.QueryPatientInfoOut patientInfo)
        {
            try
            {
                if (billitemArray == null || billitemArray.list == null)
                {
                    //operateLog.WriteLog("无待缴费数据可保存");
                    return;
                }

                // 创建JSON对象
                var jsonData = new
                {
                    patientInfo = new
                    {
                        PatientID = patientInfo?.PatientID ?? "",
                        PatientName = patientInfo?.PatientName ?? "",
                        PatientSex = patientInfo?.PatientSex ?? "",
                        PatientAge = patientInfo?.PatientAge ?? "",
                        CardNO = patientInfo?.CardNO ?? "",
                        Balance = patientInfo?.Balance ?? ""
                    },
                    queryTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    billItems = billitemArray.list.Select(item => new
                    {
                        FeeID = item.FeeID ?? "",
                        FeeName = item.FeeName ?? "",
                        FeeStatCode = item.FeeStatCode ?? "",
                        Amount = item.Amount ?? "",
                        AmountDetail = item.AmountDetail ?? "",
                        ItemName = item.ItemName ?? "",
                        ItemNumber = item.ItemNumber ?? "",
                        ItemPrice = item.ItemPrice ?? "",
                        ItemSpecification = item.ItemSpecification ?? "",
                        ItemType = item.ItemType ?? "",
                        ItemUnit = item.ItemUnit ?? "",
                        DepartmentName = item.DepartmentName ?? "",
                        DepartmentCode = item.DepartmentCode ?? "",
                        DoctorName = item.DoctorName ?? "",
                        DoctorCode = item.DoctorCode ?? "",
                        RecipeNO = item.RecipeNO ?? "",
                        RecipeTime = item.RecipeTime ?? "",
                        SeeNo = item.SeeNo ?? "",
                        RegType = item.RegType ?? "",
                        Diagnosis = item.Diagnosis ?? "",
                        Remark = item.Remark ?? "",
                        PatientBirthday = item.PatientBirthday ?? "",
                        PatientIDCardNO = item.PatientIDCardNO ?? "",
                        PatientTelephone = item.PatientTelephone ?? "",
                        CenterFeeType = item.CenterFeeType ?? "",
                        CenterItemCode = item.CenterItemCode ?? "",
                        CenterItemName = item.CenterItemName ?? "",
                        CenterItemType = item.CenterItemType ?? "",
                        MedicareInfoText = item.MedicareInfoText ?? "",
                        MoOrder = item.MoOrder ?? ""
                    }).ToArray()
                };

                // 使用JavaScriptSerializer转换为JSON字符串
                System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                string jsonString = serializer.Serialize(jsonData);
                
                // 格式化JSON（简单格式化）
                jsonString = System.Text.RegularExpressions.Regex.Replace(jsonString, @"([{,])", "$1\n  ");
                jsonString = System.Text.RegularExpressions.Regex.Replace(jsonString, @"}]", "}\n]");

                // 创建保存目录（如果不存在）
                string saveDirectory = Path.Combine(Application.StartupPath, "BillData");
                if (!Directory.Exists(saveDirectory))
                {
                    Directory.CreateDirectory(saveDirectory);
                }

                // 生成文件名（包含患者ID和时间戳）
                string fileName = $"BillData_{patientInfo?.PatientID}_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.json";
                string filePath = Path.Combine(saveDirectory, fileName);

                // 写入文件
                File.WriteAllText(filePath, jsonString, Encoding.UTF8);

                //operateLog.WriteLog($"成功保存待缴费数据到文件：{filePath}");
                MessageBox.Show($"待缴费数据已保存到：{filePath}", "保存成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                //operateLog.WriteLog("保存待缴费数据到JSON文件异常：" + ex.Message);
                MessageBox.Show("保存数据失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 更新患者信息显示
        /// </summary>
        private void UpdatePatientInfo()
        {
            try
            {
                if (patinfo != null && !string.IsNullOrEmpty(patinfo.PatientName))
                {
                    // 检查是否为同一患者（通过就诊ID判断）
                    bool isSamePatient = false;
                    if (dgv_master.Rows.Count > 0)
                    {
                        // 检查现有数据是否属于当前患者
                        string existingPatientId = dgv_master.Rows[0].Cells["就诊id"].Value?.ToString() ?? "";
                        if (!string.IsNullOrEmpty(existingPatientId) && existingPatientId == patinfo.PatientID)
                        {
                            isSamePatient = true;
                            //operateLog.WriteLog($"检测到同一患者（ID: {patinfo.PatientID}），跳过数据清空和重新查询");
                        }
                    }
                    
                    // 显示患者信息面板
                    panelPatientInfo.Visible = true;
                    
                    // 更新患者信息
                    lblPatientNameValue.Text = patinfo.PatientName ?? "";
                    lblPatientSexValue.Text = patinfo.PatientSex ?? "";
                    lblPatientAgeValue.Text = patinfo.PatientAge ?? "";
                    
                    // 格式化显示余额，添加货币符号和千位分隔符
                    if (decimal.TryParse(patinfo.Balance, out decimal balance))
                    {
                        lblBalanceValue.Text = balance.ToString("C2");
                    }
                    else
                    {
                        lblBalanceValue.Text = patinfo.Balance ?? "0.00";
                    }
                    
                    // 根据余额设置不同的颜色
                    if (decimal.TryParse(patinfo.Balance, out decimal balValue))
                    {
                        if (balValue < 100)
                        {
                            // 余额低于100元，显示红色警告
                            lblBalanceValue.ForeColor = Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(20)))), ((int)(((byte)(60)))));
                        }
                        else if (balValue < 500)
                        {
                            // 余额低于500元，显示橙色提醒
                            lblBalanceValue.ForeColor = Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(140)))), ((int)(((byte)(0)))));
                        }
                        else
                        {
                            // 余额充足，显示绿色
                            lblBalanceValue.ForeColor = Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64)))));
                        }
                    }
                    
                    // 设置textBoxPayAmount为只读状态
                    textBoxPayAmount.ReadOnly = true;
                    
                    // 如果不是同一患者，才查询患者待缴费信息
                    if (!isSamePatient)
                    {
                        QueryToPayRecipeInfoList(patinfo);
                    }
                    else
                    {
                        // 同一患者情况下，根据当前选择的处方类型过滤数据
                        string typeName = (CB_TYPE.SelectedItem as Item).Name;
                        //operateLog.WriteLog($"同一患者，根据处方类型'{typeName}'过滤现有数据");
                        
                        // 过滤主表数据
                        FilterMasterDataByType(typeName);
                        
                        // 重新计算支付金额
                        CalculateAndUpdatePayAmount();
                    }
                    
                    // 设置焦点到textBoxFKM并全选
                    textBoxFKM.Focus();
                    textBoxFKM.SelectAll();
                }
                else
                {
                    // 隐藏患者信息面板
                    panelPatientInfo.Visible = false;
                    MessageBox.Show("未找到患者信息或查询失败！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("更新患者信息UI异常：" + ex.Message);
                panelPatientInfo.Visible = false;
            }
        }

        public void QueryToPayRecipeInfoList(ServiceRef.QueryPatientInfoOut patinfo)
        {
            try
            {
                // 检查是否已有数据，避免重复查询
                if (dgv_master.Rows.Count > 0)
                {
                    operateLog.WriteLog("检测到已有数据，跳过重复查询");
                    return;
                }
                
                // 初始化与清理
                PayDetail = new Dictionary<string, QueryToPayRecipeDetailInfoOut[]>();
                string typeName = (CB_TYPE.SelectedItem as Item).Name;

                // 使用新接口：医生代码 + 最近N天 查询申请单数据
                int selectedDays = 0;
                try { selectedDays = Convert.ToInt32(CB_Date.SelectedValue); } catch { selectedDays = 10; }

                //string doctorCode = userData?.user_id ?? string.Empty;
                string patient_id = patinfo.PatientID ?? string.Empty;
                if (string.IsNullOrWhiteSpace(patient_id))
                {
                    operateLog.WriteLog("当前用户ID为空，无法查询医生申请单信息");
                    MessageBox.Show("当前用户信息缺失，无法查询医生申请单信息", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 清空现有数据
                dgv_master.Rows.Clear();
                dgv_detail.Rows.Clear();
                originalBillitemArray = null; // 不再使用旧接口返回的明细结构

                var apiResp = PatientDataService.QueryApplyInfoByDoctorCodeAndDays(patient_id, selectedDays);
                if (apiResp != null && apiResp.Success == "1" && apiResp.Data != null && apiResp.Data.Count > 0)
                {
                    foreach (var item in apiResp.Data)
                    {
                        // 根据选择的处方类型过滤数据
                        if (typeName != "全部" && !string.Equals(item.ApplyTypeName ?? string.Empty, typeName, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        int index = dgv_master.Rows.Add();
                        DataGridViewRow row = dgv_master.Rows[index];

                        // 默认不选中
                        row.Cells["ColumnSelect"].Value = false;

                        // 先填充字段，OrderName可能由异步接口再次校正
                        row.Cells["apply_master"].Value = item.ApplyNo ?? "";
                        row.Cells["就诊次数"].Value = item.VisitId ?? "";
                        row.Cells["处方类型"].Value = item.ApplyTypeName ?? "";
                        row.Cells["开单科室"].Value = ""; // 新接口未提供科室名称
                        row.Cells["开单医生"].Value = item.OrderDoc ?? "";
                        row.Cells["金额"].Value = item.TotalAmount.ToString("0.00");
                        row.Cells["就诊id"].Value = item.PatientId ?? "";
                        row.Cells["就诊流水号"].Value = item.PatientVisitId ?? "";

                        // 若新接口已返回医嘱名称，先行填充并控制按钮显示
                        string orderName = item.OrderName ?? string.Empty;
                        row.Cells["OrderName"].Value = orderName;
                        SetExecPayButtonVisibility(row, orderName.Contains("诊查费"));
                    }

                    operateLog.WriteLog($"成功加载{apiResp.Data.Count}条申请单数据，开始异步查询医嘱名称");
                }
                else
                {
                    string msg = apiResp?.Message ?? "未知错误";
                    operateLog.WriteLog($"未找到申请单数据或查询失败：{msg}");
                }
                
                // 加载待缴费信息后，计算支付金额
                CalculateAndUpdatePayAmount();
                
                // 重置所有复选框状态为未勾选
                ResetAllCheckBoxes();
                
                // 异步查询医嘱名称并填入OrderName字段
                AsyncQueryAndFillOrderNames();
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("查询待缴费信息异常：" + ex.Message);
                MessageBox.Show("查询待缴费信息失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// 将明细数据填入dgv_detail控件
        /// </summary>
        /// <param name="detailList">明细数据列表</param>
        private void FillDetailDataToGrid(ServiceRef.QueryToPayRecipeDetailInfoOut[] detailList)
        {
            try
            {
                if (detailList == null || detailList.Length == 0)
                {
                    operateLog.WriteLog("明细数据为空，不填充dgv_detail控件");
                    return;
                }
                
                // 记录数据填充开始时间
                DateTime fillStartTime = DateTime.Now;
                int processedCount = 0;
                
                // 遍历明细数据并添加到dgv_detail
                foreach (var item in detailList)
                {
                    int index = dgv_detail.Rows.Add();
                    DataGridViewRow row = dgv_detail.Rows[index];
                    
                    // 按照用户要求的字段映射填入数据
                    row.Cells["项目"].Value = item.ItemName ?? "";
                    row.Cells["单价"].Value = item.Price ?? "0.0";
                    row.Cells["数量"].Value = item.Amount ?? "0.0";
                    row.Cells["总价"].Value = item.Costs ?? "0.0";
                    row.Cells["apply_detail"].Value = item.ApplyId ?? "-";
                    
                    // 默认隐藏所有数据行
                    row.Visible = false;
                    
                    processedCount++;
                    
                    // 每处理100条记录记录一次进度
                    if (processedCount % 100 == 0)
                    {
                        DateTime progressTime = DateTime.Now;
                        TimeSpan progressDuration = progressTime - fillStartTime;
                        operateLog.WriteLog($"[性能监控] 已处理{processedCount}/{detailList.Length}条明细，当前耗时：{progressDuration.TotalMilliseconds}毫秒");
                    }
                }
                
                // 记录数据填充结束时间
                DateTime fillEndTime = DateTime.Now;
                TimeSpan fillDuration = fillEndTime - fillStartTime;
                operateLog.WriteLog($"[性能监控] 填充dgv_detail数据完成，总耗时：{fillDuration.TotalMilliseconds}毫秒，处理记录数：{detailList.Length}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("填充明细数据到dgv_detail控件异常：" + ex.Message);
                MessageBox.Show("填充明细数据失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 异步加载处方明细数据
        /// </summary>
        /// <param name="recipeNo">处方号</param>
        /// <param name="patientID">患者ID</param>
        /// <param name="recipeTime">处方时间</param>
        /// <param name="moOrder">医嘱订单号</param>
        /// <param name="itemType">项目类型</param>
        /// <param name="terminalCode">终端代码</param>
        /// <param name="yqId">医院ID</param>
        private void AsyncLoadRecipeDetails(string recipeNo, string patientID, string recipeTime, string moOrder, string itemType, string terminalCode, string yqId)
        {
            // 在UI线程上显示加载状态（使用同步上下文异步调度）
            SafeBeginInvoke(() =>
            {
                try
                {
                    lblLoadingStatus.Text = $"正在加载处方 {recipeNo} 的明细数据...";
                    lblLoadingStatus.Visible = true;
                    lblLoadingStatus.Refresh(); // 强制重绘，确保立即显示
                }
                catch (Exception ex)
                {
                    operateLog.WriteLog($"显示加载状态异常：{ex.Message}");
                }
            });
            
            // 使用Thread在后台线程执行查询（兼容.NET Framework 4.0）
            Thread thread = new Thread(() =>
            {
                try
                {
                    // 记录查询开始时间
                    DateTime queryStartTime = DateTime.Now;
                    operateLog.WriteLog($"[异步性能监控] 开始异步查询处方明细，处方号：{recipeNo}，时间：{queryStartTime:HH:mm:ss.fff}");
                    
                    // 创建服务客户端
                    ServiceRef.HospitalService_XXXXClient clientService = new ServiceRef.HospitalService_XXXXClient();
                    
                    // 设置查询参数
                    ServiceRef.QueryToPayRecipeDetailInfoIn inGetRecipeDetail = new ServiceRef.QueryToPayRecipeDetailInfoIn();
                    inGetRecipeDetail.RecipeNO = recipeNo;
                    inGetRecipeDetail.TerminalCode = terminalCode;
                    inGetRecipeDetail.PatientID = patientID;
                    inGetRecipeDetail.RecipeTime = recipeTime;
                    inGetRecipeDetail.RegFlow = "";
                    inGetRecipeDetail.yqId = yqId;
                    inGetRecipeDetail.MoOrderId = moOrder;
                    inGetRecipeDetail.ItemType = itemType;
                    
                    // 执行查询
                    ServiceRef.BaseListOfQueryToPayRecipeDetailInfoOuto4BIDE2W detailArray = clientService.QueryToPayRecipeDetailInfoList(inGetRecipeDetail);
                    
                    // 记录查询结束时间
                    DateTime queryEndTime = DateTime.Now;
                    TimeSpan queryDuration = queryEndTime - queryStartTime;
                    operateLog.WriteLog($"[异步性能监控] 处方明细查询完成，耗时：{queryDuration.TotalMilliseconds}毫秒，结果状态：{detailArray.Result}，明细数量：{(detailArray.list != null ? detailArray.list.Length : 0)}");
                    
                    // 如果查询成功，更新UI
                    if (detailArray.Result == "0" && detailArray.list != null && detailArray.list.Length > 0)
                    {
                        // 在UI线程上更新界面
                        this.Invoke(new Action(() =>
                        {
                            try
                            {
                                // 更新PayDetail字典
                                if (!PayDetail.ContainsKey(recipeNo))
                                {
                                    PayDetail.Add(recipeNo, detailArray.list);
                                }
                                else
                                {
                                    PayDetail[recipeNo] = detailArray.list;
                                }
                                
                                // 填充明细数据到dgv_detail
                                FillDetailDataToGrid(detailArray.list);
                                
                                // 数据加载完成后，如果CB_SHOWDETAIL被勾选，则调用过滤方法显示相关数据
                                if (CB_SHOWDETAIL.Checked)
                                {
                                    // 获取当前选中的申请单号
                                    string currentApplyMaster = "";
                                    foreach (DataGridViewRow masterRow in dgv_master.Rows)
                                    {
                                        bool isChecked = Convert.ToBoolean(masterRow.Cells["ColumnSelect"].Value ?? false);
                                        if (isChecked)
                                        {
                                            currentApplyMaster = masterRow.Cells["apply_master"].Value?.ToString() ?? "";
                                            break;
                                        }
                                    }
                                    
                                    if (!string.IsNullOrEmpty(currentApplyMaster))
                                    {
                                        FilterDetailData(currentApplyMaster, true);
                                        operateLog.WriteLog($"[异步性能监控] 处方{recipeNo}明细数据已过滤显示，申请单号：{currentApplyMaster}");
                                    }
                                }
                                
                                // 更新对应处方的金额
                                //UpdateRecipeAmountInGrid(recipeNo, detailArray.list.Sum(x => Convert.ToDecimal(x.Costs)).ToString());
                                
                                // 隐藏加载状态
                                lblLoadingStatus.Visible = false;
                                
                                operateLog.WriteLog($"[异步性能监控] 处方{recipeNo}明细数据已加载到UI，明细数量：{detailArray.list.Length}");
                            }
                            catch (Exception ex)
                            {
                                operateLog.WriteLog($"[异步性能监控] 更新UI异常：{ex.Message}");
                                
                                // 隐藏加载状态
                                lblLoadingStatus.Visible = false;
                            }
                        }));
                    }
                    else
                    {
                        operateLog.WriteLog($"[异步性能监控] 处方{recipeNo}明细查询失败或无数据，结果状态：{detailArray.Result}");
                        
                        // 在UI线程上隐藏加载状态（使用同步上下文异步调度）
                        SafeBeginInvoke(() =>
                        {
                            try
                            {
                                lblLoadingStatus.Visible = false;
                            }
                            catch (Exception ex)
                            {
                                operateLog.WriteLog($"隐藏加载状态异常：{ex.Message}");
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                    operateLog.WriteLog($"[异步性能监控] 异步查询处方明细异常：{ex.Message}");
                    
                    // 在UI线程上显示错误信息并隐藏加载状态（使用同步上下文异步调度）
                    SafeBeginInvoke(() =>
                    {
                        try
                        {
                            lblLoadingStatus.Visible = false;
                            MessageBox.Show($"查询处方明细失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        catch (Exception uiEx)
                        {
                            operateLog.WriteLog($"显示错误信息异常：{uiEx.Message}");
                        }
                    });
                }
            });
            
            // 设置线程为后台线程并启动
            thread.IsBackground = true;
            thread.Start();
        }

        /// <summary>
        /// 更新dgv_master中对应处方的金额
        /// </summary>
        /// <param name="recipeNo">处方号</param>
        /// <param name="amount">金额</param>
        private void UpdateRecipeAmountInGrid(string recipeNo, string amount)
        {
            try
            {
                // 遍历dgv_master中的所有行
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    // 找到匹配的处方号
                    if (row.Cells["apply_master"].Value?.ToString() == recipeNo)
                    {
                        // 更新金额
                        row.Cells["金额"].Value = amount;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"更新处方金额异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 初始化DataGridView控件
        /// </summary>
        private void InitializeDataGridView()
        {
            try
            {
                // 为dgv_master添加全选功能
                DatagridViewCheckBoxHeaderCell headerCell = new DatagridViewCheckBoxHeaderCell();
                headerCell.OnCheckBoxClicked += new CheckBoxClickedHandler(HeaderCell_OnCheckBoxClicked);
                ColumnSelect.HeaderCell = headerCell;
                
                // 设置dgv_master的事件处理
                dgv_master.CellValueChanged += new DataGridViewCellEventHandler(dgv_master_CellValueChanged);
                dgv_master.CurrentCellDirtyStateChanged += new EventHandler(dgv_master_CurrentCellDirtyStateChanged);
                dgv_master.CellClick += new DataGridViewCellEventHandler(dgv_master_CellClick);
                dgv_master.CellContentClick += new DataGridViewCellEventHandler(dgv_master_CellContentClick);
                
                // 设置dgv_detail控件可见，但数据行默认不可见
                dgv_detail.Visible = true;
                
                operateLog.WriteLog("DataGridView初始化完成");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("初始化DataGridView异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 全选/取消全选事件处理
        /// </summary>
        private void HeaderCell_OnCheckBoxClicked(bool isChecked)
        {
            try
            {
                // 开启批量编辑
                dgv_master.BeginEdit(false);
                
                // 遍历所有行，设置复选框状态
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    row.Cells["ColumnSelect"].Value = isChecked;
                }
                
                // 结束批量编辑
                dgv_master.EndEdit();
                
                // 刷新显示
                dgv_master.Refresh();
                
                // 设置焦点到textBoxFKM并全选
                textBoxFKM.Focus();
                textBoxFKM.SelectAll();
                
                operateLog.WriteLog($"全选操作完成，状态：{isChecked}，已设置焦点到textBoxFKM并全选");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("全选操作异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 单元格值变化事件处理
        /// </summary>
        private void dgv_master_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // 如果是复选框列
                if (e.ColumnIndex == ColumnSelect.Index && e.RowIndex >= 0)
                {
                    bool isChecked = Convert.ToBoolean(dgv_master.Rows[e.RowIndex].Cells["ColumnSelect"].Value);
                    string applyMaster = dgv_master.Rows[e.RowIndex].Cells["apply_master"].Value?.ToString() ?? "";
                    
                    // 如果CB_SHOWDETAIL勾选且选中了某行，检查是否需要加载明细数据
                    if (CB_SHOWDETAIL.Checked && isChecked)
                    {
                        // 检查dgv_detail中是否已有该申请单的明细数据
                        bool hasDetailData = false;
                        foreach (DataGridViewRow detailRow in dgv_detail.Rows)
                        {
                            string detailApply = detailRow.Cells["apply_detail"].Value?.ToString() ?? "";
                            if (detailApply == applyMaster)
                            {
                                hasDetailData = true;
                                break;
                            }
                        }
                        
                        // 如果没有明细数据，则调用接口查询
                        if (!hasDetailData)
                        {
                            // 从dgv_master获取相关信息用于调用接口
                            DataGridViewRow masterRow = dgv_master.Rows[e.RowIndex];
                            string patientID = masterRow.Cells["就诊id"].Value?.ToString() ?? "";
                            
                            // 需要从原始数据中获取其他参数，这里先记录日志
                            operateLog.WriteLog($"需要为申请单 {applyMaster} 加载明细数据，患者ID：{patientID}");
                            
                            // 由于需要更多参数来调用AsyncLoadRecipeDetails，这里暂时记录需要加载的申请单
                            // 实际实现中需要保存原始查询结果以便获取完整参数
                            LoadRecipeDetailsForApply(applyMaster, patientID);
                        }
                    }
                    
                    // 根据选择状态过滤dgv_detail数据（如果CB_SHOWDETAIL勾选）
                    if (CB_SHOWDETAIL.Checked)
                    {
                        FilterDetailData(applyMaster, isChecked);
                    }
                    
                    // 计算勾选申请单的金额汇总并更新支付金额
                    CalculateAndUpdatePayAmount();
                    
                    // 设置焦点到textBoxFKM并全选
                    textBoxFKM.Focus();
                    textBoxFKM.SelectAll();
                    
                    operateLog.WriteLog($"行选择变化，行索引：{e.RowIndex}，选择状态：{isChecked}，申请单号：{applyMaster}，CB_SHOWDETAIL状态：{CB_SHOWDETAIL.Checked}，已设置焦点到textBoxFKM并全选");
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("单元格值变化处理异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 为指定的申请单加载明细数据
        /// </summary>
        /// <param name="applyMaster">申请单号</param>
        /// <param name="patientID">患者ID</param>
        private void LoadRecipeDetailsForApply(string applyMaster, string patientID)
        {
            try
            {
                if (originalBillitemArray == null || originalBillitemArray.list == null)
                {
                    operateLog.WriteLog($"原始数据为空，无法加载申请单 {applyMaster} 的明细数据");
                    return;
                }
                
                // 从原始数据中查找对应的申请单记录
                var targetRecord = originalBillitemArray.list.FirstOrDefault(x => x.RecipeNO == applyMaster);
                if (targetRecord == null)
                {
                    operateLog.WriteLog($"在原始数据中未找到申请单 {applyMaster} 的记录");
                    return;
                }
                
                // 获取原始查询参数（与QueryToPayRecipeInfoList方法中的参数保持一致）
                string terminalCode = "001";
                string yqId = "LZ001";
                
                operateLog.WriteLog($"开始为申请单 {applyMaster} 加载明细数据，患者ID：{patientID}");
                
                // 调用异步加载明细数据方法
                AsyncLoadRecipeDetails(
                    targetRecord.RecipeNO,
                    patientID,
                    targetRecord.RecipeTime.ToString(),
                    targetRecord.MoOrder,
                    targetRecord.ItemType,
                    terminalCode,
                    yqId
                );
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"为申请单 {applyMaster} 加载明细数据异常：{ex.Message}");
            }
        }
        
        /// <summary>
        /// 当前单元格脏状态变化事件处理
        /// </summary>
        private void dgv_master_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            try
            {
                if (dgv_master.IsCurrentCellDirty)
                {
                    // 提交编辑
                    dgv_master.CommitEdit(DataGridViewDataErrorContexts.Commit);
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("提交编辑异常：" + ex.Message);
            }
        }

        /// <summary>
        /// dgv_master的CellContentClick事件处理方法
        /// </summary>
        private void dgv_master_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // 检查是否点击了有效行和复选框列
                if (e.RowIndex >= 0 && e.ColumnIndex == ColumnSelect.Index)
                {
                    // 提交编辑，确保复选框状态更新
                    dgv_master.CommitEdit(DataGridViewDataErrorContexts.Commit);
                    
                    // 设置焦点到textBoxFKM并全选
                    textBoxFKM.Focus();
                    textBoxFKM.SelectAll();
                    
                    operateLog.WriteLog($"点击了复选框列，行索引：{e.RowIndex}，已设置焦点到textBoxFKM并全选");
                }
                // 检查是否点击了execPay按钮列
                else if (e.RowIndex >= 0 && dgv_master.Columns[e.ColumnIndex].Name == "execPay")
                {
                    DataGridViewRow row = dgv_master.Rows[e.RowIndex];
                    
                    // 多重检查确保按钮真正可用：
                    // 1. 检查按钮值不为空
                    // 2. 检查按钮不是只读状态
                    // 3. 检查按钮颜色不是透明（即未被隐藏）
                    bool isButtonVisible = row.Cells["execPay"].Value != null && 
                                         !string.IsNullOrEmpty(row.Cells["execPay"].Value.ToString()) &&
                                         !row.Cells["execPay"].ReadOnly &&
                                         row.Cells["execPay"].Style.ForeColor != System.Drawing.Color.Transparent;
                    
                    if (isButtonVisible)
                    {
                        operateLog.WriteLog($"点击了execPay按钮，行索引：{e.RowIndex}");
                        
                        // 1. 检查CB_SHOWDETAIL状态，如未勾选则自动勾选
                        if (!CB_SHOWDETAIL.Checked)
                        {
                            CB_SHOWDETAIL.Checked = true;
                            operateLog.WriteLog("自动勾选CB_SHOWDETAIL");
                        }
                        
                        // 2. 自动勾选该行的复选框
                        row.Cells["ColumnSelect"].Value = true;
                        dgv_master.CommitEdit(DataGridViewDataErrorContexts.Commit);
                        operateLog.WriteLog($"自动勾选行{e.RowIndex}的复选框");
                        
                        // 3. 设置焦点到textBoxFKM并全选
                        textBoxFKM.Focus();
                        textBoxFKM.SelectAll();
                        
                        operateLog.WriteLog("execPay按钮点击处理完成");
                    }
                    else
                    {
                        // 按钮被隐藏时，记录点击尝试但不执行任何操作
                        operateLog.WriteLog($"尝试点击隐藏的execPay按钮，行索引：{e.RowIndex}，操作被阻止");
                    }
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("dgv_master_CellContentClick事件处理异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// dgv_master的CellClick事件处理方法
        /// </summary>
        private void dgv_master_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // 检查是否点击了有效行
                if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
                {
                    // 获取点击的列名
                    string columnName = dgv_master.Columns[e.ColumnIndex].Name;
                    
                    // 如果是申请单号列或其他需要查阅的列（排除复选框列，因为已在CellContentClick中处理）
                    if (columnName == "apply_master" || columnName == "就诊id")
                    {
                        // 设置焦点到textBoxFKM并全选
                        textBoxFKM.Focus();
                        textBoxFKM.SelectAll();
                        
                        operateLog.WriteLog($"点击了{columnName}列，已设置焦点到textBoxFKM并全选");
                    }
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("dgv_master_CellClick事件处理异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 根据apply_master过滤dgv_detail数据
        /// </summary>
        /// <param name="applyMaster">申请单号</param>
        /// <param name="isChecked">是否选中</param>
        private void FilterDetailData(string applyMaster, bool isChecked)
        {
            try
            {
                // 获取所有选中的申请单号
                var selectedApplyMasters = new List<string>();
                foreach (DataGridViewRow masterRow in dgv_master.Rows)
                {
                    if (Convert.ToBoolean(masterRow.Cells["ColumnSelect"].Value))
                    {
                        string masterApply = masterRow.Cells["apply_master"].Value?.ToString() ?? "";
                        if (!string.IsNullOrEmpty(masterApply))
                        {
                            selectedApplyMasters.Add(masterApply);
                        }
                    }
                }
                
                // 根据选中的申请单号过滤显示detail数据
                for (int i = 0; i < dgv_detail.Rows.Count; i++)
                {
                    string applyDetail = dgv_detail.Rows[i].Cells["apply_detail"].Value?.ToString() ?? "";
                    
                    // 如果有选中的申请单号，显示匹配的detail数据
                    if (selectedApplyMasters.Count > 0)
                    {
                        dgv_detail.Rows[i].Visible = selectedApplyMasters.Contains(applyDetail);
                    }
                    else
                    {
                        // 如果没有选中的行，隐藏所有detail数据行
                        dgv_detail.Rows[i].Visible = false;
                    }
                }
                
                operateLog.WriteLog($"过滤detail数据完成，申请单号：{applyMaster}，选择状态：{isChecked}，选中申请单数量：{selectedApplyMasters.Count}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("过滤detail数据异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 计算勾选申请单的金额汇总并更新支付金额
        /// </summary>
        private void CalculateAndUpdatePayAmount()
        {
            try
            {
                decimal totalAmount = 0;
                
                // 遍历所有行，计算勾选申请单的金额汇总
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    if (Convert.ToBoolean(row.Cells["ColumnSelect"].Value))
                    {
                        string amountStr = row.Cells["金额"].Value?.ToString() ?? "0";
                        if (decimal.TryParse(amountStr, out decimal amount))
                        {
                            totalAmount += amount;
                        }
                    }
                }
                
                // 获取卡余额
                decimal cardBalance = 0;
                string balanceStr = lblBalanceValue.Text;
                
                // 移除货币符号和千位分隔符，只保留数字和小数点
                if (balanceStr.StartsWith("¥"))
                {
                    balanceStr = balanceStr.Substring(1);
                }
                balanceStr = balanceStr.Replace(",", "");
                
                if (decimal.TryParse(balanceStr, out decimal balance))
                {
                    cardBalance = balance;
                }
                
                // 计算支付金额：金额汇总与卡余额的差值
                decimal payAmount = totalAmount - cardBalance;
                
                // 如果卡余额大于金额汇总，显示为0
                if (cardBalance >= totalAmount)
                {
                    payAmount = 0;
                }
                
                // 更新textBoxPayAmount的值
                textBoxPayAmount.Text = payAmount.ToString("F2");
                
                operateLog.WriteLog($"计算支付金额完成，金额汇总：{totalAmount}，卡余额：{cardBalance}，支付金额：{payAmount}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("计算支付金额异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 手工填写金额按钮点击事件
        /// </summary>
        private void bt_byhand_Click(object sender, EventArgs e)
        {
            try
            {
                // 设置textBoxPayAmount为可编辑状态
                textBoxPayAmount.ReadOnly = false;
                
                // 设置值为0
                textBoxPayAmount.Text = "0.00";
                
                // 设置焦点到textBoxPayAmount，方便用户输入
                textBoxPayAmount.Focus();
                textBoxPayAmount.SelectAll();
                
                operateLog.WriteLog("手工填写金额按钮被点击，textBoxPayAmount已设置为可编辑状态");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("手工填写金额按钮点击事件异常：" + ex.Message);
            }
        }

        #endregion
        #region 初始化界面
        void setCmd()
        {
            List<Item> item = new List<Item>();
            for (int i = 1; i < 8; i++)
            {
                item.Add(new Item() { ID = i, Name = "查询" + i.ToString() + "天" });
            }
            item.Add(new Item() { ID = 30, Name = "查询一个月" });
            item.Add(new Item() { ID = 60, Name = "查询两个月" });
            item.Add(new Item() { ID = 90, Name = "查询三个月" });
            item.Add(new Item() { ID = 365, Name = "查询一年" });
            CB_Date.DataSource = item;
            CB_Date.DisplayMember = "Name"; // 显示Name属性
            CB_Date.ValueMember = "ID"; // 存储ID属性作为值
            CB_Date.SelectedIndex = 0;
            CB_Date.SelectionChangeCommitted += new EventHandler(CB_DATE_SelectedIndexChanged);

            List<Item> itemType = new List<Item>();
            itemType.Add(new Item() { ID = 0, Name = "全部" });
            itemType.Add(new Item() { ID = 1, Name = "处方单" });
            itemType.Add(new Item() { ID = 2, Name = "检查单" });
            itemType.Add(new Item() { ID = 3, Name = "检验单" });
            itemType.Add(new Item() { ID = 3, Name = "治疗单" });
            CB_TYPE.DataSource = itemType;
            CB_TYPE.DisplayMember = "Name"; // 显示Name属性
            CB_TYPE.ValueMember = "ID"; // 存储ID属性作为值
            CB_TYPE.SelectedIndex = 0;
            CB_TYPE.SelectedIndexChanged += new EventHandler(CB_TYPE_SelectedIndexChanged);
            //comboBox2.SelectionChangeCommitted += new EventHandler(comboBox2_SelectedIndexChanged);

            ////绑定检查检验互认事件
            //bt_lis.Click += new EventHandler(openLisExamWebView);
            //bt_exam.Click += new EventHandler(openLisExamWebView);

            //// 加载本地数据
            //LoadLocalData();
        }
        public DateTime getNowDateTime()
        {
            DateTime date = DateTime.Now;
            try
            {
                ServiceRef.ResultBase resTime = new ServiceRef.ResultBase();
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                resTime = clientService.QueryHISTime("001", "");
                if (resTime.Result == "0")
                {
                    date = DateTime.Parse(resTime.ReturnValue);
                }
            }
            catch (Exception)
            {

            }
            return date;
        }

        /// <summary>
        /// 将待缴费明细数据保存到JSON文件
        /// </summary>
        /// <param name="detailArray">待缴费明细数据</param>
        /// <param name="recipeNo">处方号</param>
        /// <param name="patinfo">患者信息</param>
        private void SaveDetailDataToJson(ServiceRef.BaseListOfQueryToPayRecipeDetailInfoOuto4BIDE2W detailArray, string recipeNo, ServiceRef.QueryPatientInfoOut patinfo)
        {
            try
            {
                if (detailArray == null || detailArray.list == null || detailArray.list.Length == 0)
                {
                    operateLog.WriteLog("待缴费明细数据为空，不保存JSON文件");
                    return;
                }

                // 创建保存目录
                string billDataDir = Path.Combine(Application.StartupPath, "BillData");
                if (!Directory.Exists(billDataDir))
                {
                    Directory.CreateDirectory(billDataDir);
                }

                // 创建文件名：患者ID_处方号_明细_查询时间.json
                string fileName = $"{patinfo.PatientID}_{recipeNo}_detail_{DateTime.Now:yyyyMMdd_HHmmss}.json";
                string filePath = Path.Combine(billDataDir, fileName);

                // 构建JSON数据结构
                var jsonData = new
                {
                    queryTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    patientInfo = new
                    {
                        patientID = patinfo.PatientID,
                        patientName = patinfo.PatientName,
                        cardNO = patinfo.CardNO,
                        idCardNO = patinfo.PatientIDCardNO
                    },
                    recipeNo = recipeNo,
                    result = detailArray.Result,
                    message = detailArray.Message,
                    detailCount = detailArray.list.Length,
                    details = detailArray.list.Select(item => new
                    {
                        // 基本信息
                        itemCode = item.ItemCode,
                        itemName = item.ItemName,
                        itemSpecification = item.Spec,
                        itemUnit = item.UnitName,
                        itemPrice = item.Price,
                        quantity = item.Quantity,
                        costs = item.Costs,
                        amount = item.Amount,
                        
                        // 医疗信息
                        centerItemCode = item.CenterItemCode,
                        centerItemName = item.CenterItemName,
                        centerItemType = item.CenterItemType,
                        centerFeeType = item.CenterFeeType,
                        itemClass = item.ItemClass,
                        itemClassName = item.ItemClassName,
                        
                        // 科室和医生信息
                        deptCode = item.DeptCode,
                        deptName = item.DeptName,
                        doctCode = item.DoctCode,
                        doctName = item.DoctName,
                        performedByDeptCode = item.PerformedByDeptCode,
                        performedByDeptName = item.PerformedByDeptName,
                        
                        // 处方信息
                        recipeNO = item.RecipeNO,
                        moOrder = item.MoOrder,
                        orderDate = item.OrderDate,
                        chargeDate = item.ChargeDate,
                        chargedStatus = item.ChargedStatus,
                        
                        // 其他信息
                        applyClass = item.ApplyClass,
                        applyClassName = item.ApplyClassName,
                        applyId = item.ApplyId,
                        autoRatio = item.AutoRatio,
                        clinicId = item.ClinicId,
                        clinicItemCode = item.ClinicItemCode,
                        currentNursingUnit = item.CurrentNursingUnit,
                        days = item.Days,
                        diagByCode = item.DiagByCode,
                        diagEmpId = item.DiagEmpId,
                        diagEmpName = item.DiagEmpName,
                        diagIcd = item.DiagIcd,
                        diagName = item.DiagName,
                        diags = item.Diags,
                        duration = item.Duration,
                        durationUnitName = item.DurationUnitName,
                        enterDate = item.EnterDate,
                        externalId = item.ExternalId,
                        factor = item.Factor,
                        feeCode = item.FeeCode,
                        feeName = item.FeeName,
                        freqName = item.FreqName,
                        freqUnitName = item.FreqUnitName,
                        inClassOnRcptCode = item.InClassOnRcptCode,
                        inClassOnRcptCodeName = item.InClassOnRcptCodeName,
                        inOutFlag = item.InOutFlag,
                        insurLevelCode = item.InsurLevelCode,
                        insurLevelName = item.InsurLevelName,
                        insuranceType = item.InsuranceType,
                        invoicePrintStatus = item.InvoicePrintStatus,
                        isCharge = item.IsCharge,
                        itemId = item.ItemId,
                        itemNo = item.ItemNo,
                        itemNumber = item.ItemNumber,
                        medUnitName = item.MedUnitName,
                        mipsEmpIdBegDoct = item.MipsEmpIdBegDoct,
                        operName = item.OperName,
                        orderBeginDate = item.OrderBeginDate,
                        orderByDeptCode = item.OrderByDeptCode,
                        orderByDeptName = item.OrderByDeptName,
                        orderId = item.OrderId,
                        orderItemDetailId = item.OrderItemDetailId,
                        orgIdHospital = item.OrgIdHospital,
                        outClassOnRcptCode = item.OutClassOnRcptCode,
                        outClassOnRcptCodeName = item.OutClassOnRcptCodeName,
                        patientId = item.PatientId,
                        perMed = item.PerMed,
                        ratio = item.Ratio,
                        remark = item.Remark,
                        retailFactor = item.RetailFactor,
                        salesPrice = item.SalesPrice,
                        spellCode = item.SpellCode,
                        subjCode = item.SubjCode,
                        unitQuantity = item.UnitQuantity,
                        use = item.Use,
                        visitId = item.VisitId
                    }).ToArray()
                };

                // 使用JavaScriptSerializer序列化JSON
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                serializer.MaxJsonLength = Int32.MaxValue; // 设置最大JSON长度
                string jsonContent = serializer.Serialize(jsonData);

                // 简单格式化JSON（添加缩进）
                jsonContent = Regex.Replace(jsonContent, "([{\\[])\\s*", "$1\n  ");
                jsonContent = Regex.Replace(jsonContent, "([,\\}])\\s*", "$1\n");
                jsonContent = Regex.Replace(jsonContent, "(\\])\\s*", "$1\n");

                // 写入文件
                File.WriteAllText(filePath, jsonContent, Encoding.UTF8);
                operateLog.WriteLog($"待缴费明细数据已保存到: {filePath}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("保存待缴费明细数据到JSON文件失败: " + ex.Message);
            }
        }

        private void CB_DATE_SelectedIndexChanged(object sender, EventArgs e)
        {
            //bt_lis.Visible = false;
            //bt_exam.Visible = false;
            //reportUrl = string.Empty;
            //tb_reporturl.Text = string.Empty;
            int selectedValue = Convert.ToInt32(CB_Date.SelectedValue); // 如果ValueMember设置正确的话
            EndDate = getNowDateTime().AddDays(-selectedValue).ToString("yyyy-MM-dd");
            //cmd.ShowOpaqueLayer(this, 100, true);
            //lblwaittip.Visible = false;
            //this.pictureBox1.Visible = false;
            //this.OutTradeNo.Text = "";
            //string str = patinfo.CardNO;
            //this.textBoxPayAmount.Text = "0";
            //threadQueryPatient = new Thread(new ParameterizedThreadStart(DoWork));
            //threadQueryPatient.Start(str); // 直接传递参数给DoWork方法
            
            // 如果patinfo不为空，自动触发查询
            if (patinfo != null && !string.IsNullOrEmpty(patinfo.CardNO))
            {
                // 清空现有数据
                dgv_master.Rows.Clear();
                dgv_detail.Rows.Clear();
                
                // 启动查询线程
                threadQueryPatient = new Thread(new ParameterizedThreadStart(DoWork));
                threadQueryPatient.Start(patinfo.CardNO);
                
                operateLog.WriteLog("CB_Date变化，自动触发查询患者信息，卡号：" + patinfo.CardNO);
            }
        }

        /// <summary>
        /// 根据处方类型过滤主表数据
        /// </summary>
        /// <param name="typeName">处方类型名称</param>
        private void FilterMasterDataByType(string typeName)
        {
            try
            {
                // 遍历所有行，根据类型过滤显示
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    if (typeName == "全部")
                    {
                        // 显示所有行
                        row.Visible = true;
                    }
                    else
                    {
                        // 根据处方类型过滤
                        string itemType = row.Cells["处方类型"].Value?.ToString() ?? "";
                        row.Visible = (itemType == typeName);
                    }
                }
                
                // 重置所有复选框状态为未勾选
                ResetAllCheckBoxes();
                
                // 重新过滤明细数据并计算金额
                FilterDetailDataForVisibleRows();
                CalculateAndUpdatePayAmount();
                
                operateLog.WriteLog($"根据处方类型过滤完成，类型：{typeName}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"过滤主表数据异常：{ex.Message}");
            }
        }
        
        /// <summary>
        /// 为所有可见行过滤明细数据
        /// </summary>
        private void FilterDetailDataForVisibleRows()
        {
            try
            {
                // 先隐藏所有明细数据
                foreach (DataGridViewRow detailRow in dgv_detail.Rows)
                {
                    detailRow.Visible = false;
                }
                
                // 获取所有可见主表行的申请单号
                List<string> visibleApplyMasters = new List<string>();
                foreach (DataGridViewRow masterRow in dgv_master.Rows)
                {
                    if (masterRow.Visible && Convert.ToBoolean(masterRow.Cells["ColumnSelect"].Value))
                    {
                        string applyMaster = masterRow.Cells["apply_master"].Value?.ToString() ?? "";
                        if (!string.IsNullOrEmpty(applyMaster))
                        {
                            visibleApplyMasters.Add(applyMaster);
                        }
                    }
                }
                
                // 显示匹配的明细数据
                foreach (DataGridViewRow detailRow in dgv_detail.Rows)
                {
                    string applyDetail = detailRow.Cells["apply_detail"].Value?.ToString() ?? "";
                    if (visibleApplyMasters.Contains(applyDetail))
                    {
                        detailRow.Visible = true;
                    }
                }
                
                operateLog.WriteLog($"明细数据过滤完成，可见主表行数：{visibleApplyMasters.Count}");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"过滤明细数据异常：{ex.Message}");
            }
        }

        private void CB_TYPE_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 获取选中的处方类型
            string selectedType = CB_TYPE.SelectedValue.ToString();
            
            // 如果patinfo不为空，重新过滤已加载的数据而不是重新查询
            if (patinfo != null && !string.IsNullOrEmpty(patinfo.CardNO))
            {
                // 检查是否已有数据，如果有则只过滤而不重新查询
                if (dgv_master.Rows.Count > 0)
                {
                    // 过滤现有数据
                    FilterMasterDataByType(selectedType);
                    operateLog.WriteLog("CB_TYPE变化，仅过滤现有数据，不重新查询，选择类型：" + selectedType);
                }
                else
                {
                    // 如果没有数据，则触发查询
                    threadQueryPatient = new Thread(new ParameterizedThreadStart(DoWork));
                    threadQueryPatient.Start(patinfo.CardNO);
                    operateLog.WriteLog("CB_TYPE变化，但无现有数据，触发查询患者信息，卡号：" + patinfo.CardNO + "，选择类型：" + selectedType);
                }
            }
        }
        #endregion

        private void tb_qrcode_Click(object sender, EventArgs e)
        {
            //tb_qrcode.Text=string.Empty;
            tb_qrcode.SelectAll();
            tb_qrcode.Focus();
        }

        /// <summary>
        /// 刷新病人列表按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_reflash_patlist_Click(object sender, EventArgs e)
        {
            try
            {
                // 在后台线程执行数据刷新任务，避免阻塞UI
                ThreadPool.QueueUserWorkItem(state =>
                {
                    try
                    {
                        // 清空本地数据库
                        bool clearResult = LocalDbHelper.ClearAllData();

                        // 在UI线程更新界面
                        if (this.Created)
                        {
                            this.BeginInvoke(new MethodInvoker(() =>
                            {
                                // 刷新数据窗口显示清空后的状态
                                LoadLocalData();

                                LoadDoctorPatientRecords();
                            }));
                        }
                    }
                    catch (Exception ex)
                    {
                        operateLog.WriteLog($"数据刷新时发生错误: {ex.Message}");
                        if (this.Created)
                        {
                            this.BeginInvoke(new Action(() => {
                                MessageBox.Show("数据刷新失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }));
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"启动数据刷新任务时发生错误: {ex.Message}");
                MessageBox.Show("启动数据刷新任务失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 加载本地数据到dgvLocalData控件
        /// </summary>
        private void LoadLocalData()
        {
            try
            {
                dgvLocalData.Rows.Clear();
                
                // 订阅 CellFormatting 事件
                dgvLocalData.CellFormatting -= dgvLocalData_CellFormatting; // 先取消订阅避免重复
                dgvLocalData.CellFormatting += dgvLocalData_CellFormatting;
                
                // 订阅 CellContentClick 事件，用于处理按钮点击
                dgvLocalData.CellContentClick -= dgvLocalData_CellContentClick; // 先取消订阅避免重复
                dgvLocalData.CellContentClick += dgvLocalData_CellContentClick;
                
                // 从LocalDbHelper获取数据
                var localData = LocalDbHelper.GetTodayPatientVisitData();
                
                if (localData != null && localData.Count > 0)
                {
                    // 按outP_VISIT_ID降序排序（最大的在上面）
                    var sortedData = localData.OrderByDescending(x => 
                    {
                        if (x.ContainsKey("outP_VISIT_ID") && long.TryParse(x["outP_VISIT_ID"], out long id))
                            return id;
                        return 0;
                    }).ToList();
                    
                    foreach (var item in sortedData)
                    {
                        int rowIndex = dgvLocalData.Rows.Add();
                        
                        // 查找列并设置值 - 使用安全的列检查和索引访问
                        var colViewButton = dgvLocalData.Columns["colViewButton"];
                        var colPatientName = dgvLocalData.Columns["colPatientName"];
                        var colOrderNames = dgvLocalData.Columns["colOrderNames"];
                        var colOutpVisitId = dgvLocalData.Columns["colOutpVisitId"];
                        var colPatLevel = dgvLocalData.Columns["colPatLevel"];
                        var colSpecialName = dgvLocalData.Columns["colSpecialName"];
                        var outp_visit_id = dgvLocalData.Columns["outp_visit_id"];
                        var colLisCount = dgvLocalData.Columns["colLisCount"];
                        var colExamCount = dgvLocalData.Columns["colExamCount"];
                        var colRegistrationFeeStatus = dgvLocalData.Columns["colRegistrationFeeStatus"];
                        
                        if (colViewButton != null) dgvLocalData.Rows[rowIndex].Cells[colViewButton.Index].Value = "查阅";
                        if (colPatientName != null) dgvLocalData.Rows[rowIndex].Cells[colPatientName.Index].Value = item.ContainsKey("patI_NAME") ? item["patI_NAME"] : "";
                        if (colOrderNames != null) dgvLocalData.Rows[rowIndex].Cells[colOrderNames.Index].Value = item.ContainsKey("ordeR_NAMES") ? item["ordeR_NAMES"] : "";
                        if (colOutpVisitId != null) dgvLocalData.Rows[rowIndex].Cells[colOutpVisitId.Index].Value = item.ContainsKey("patienT_ID") ? item["patienT_ID"] : "";
                        if (colPatLevel != null) dgvLocalData.Rows[rowIndex].Cells[colPatLevel.Index].Value = item.ContainsKey("paT_LEVEL") ? item["paT_LEVEL"] : "";
                        if (colSpecialName != null) dgvLocalData.Rows[rowIndex].Cells[colSpecialName.Index].Value = item.ContainsKey("outP_SPECIAL_NAME") ? item["outP_SPECIAL_NAME"] : "";
                        if (outp_visit_id != null) dgvLocalData.Rows[rowIndex].Cells[outp_visit_id.Index].Value = item.ContainsKey("outP_VISIT_ID") ? item["outP_VISIT_ID"] : "";

                        // 设置互认检验按钮
                        string lisCount = item.ContainsKey("liS_COUNT") ? item["liS_COUNT"] : "0";
                        if (colLisCount != null) 
                        {
                            dgvLocalData.Rows[rowIndex].Cells[colLisCount.Index].Value = lisCount;
                            if (lisCount != "0")
                            {
                                dgvLocalData.Rows[rowIndex].Cells[colLisCount.Index].Style.BackColor = Color.MediumSpringGreen;
                            }
                        }
                        
                        // 设置互认检查按钮
                        string examCount = item.ContainsKey("exaM_COUNT") ? item["exaM_COUNT"] : "0";
                        if (colExamCount != null) 
                        {
                            dgvLocalData.Rows[rowIndex].Cells[colExamCount.Index].Value = examCount;
                            if (examCount != "0")
                            {
                                dgvLocalData.Rows[rowIndex].Cells[colExamCount.Index].Style.BackColor = Color.PeachPuff;
                            }
                        }
                        
                        if (colRegistrationFeeStatus != null) 
                        {
                            dgvLocalData.Rows[rowIndex].Cells[colRegistrationFeeStatus.Index].Value = item.ContainsKey("registratioN_FEE_STATUS") ? item["registratioN_FEE_STATUS"] : "";
                        }
                        
                        // 存储完整的数据对象到Tag中，方便后续使用
                        dgvLocalData.Rows[rowIndex].Tag = item;
                    }
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("加载本地数据失败: " + ex.Message);
                MessageBox.Show("加载本地数据失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// dgvLocalData的CellFormatting事件处理方法
        /// </summary>
        private void dgvLocalData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                DataGridView dataGridView = (DataGridView)sender;
                DataGridViewRow row = dataGridView.Rows[e.RowIndex];

                // 找到 colOrderNames 列的索引
                if (dataGridView.Columns.Contains("colOrderNames"))
                {
                    int orderNamesColumnIndex = dataGridView.Columns["colOrderNames"].Index;
                    DataGridViewCell orderNamesCell = row.Cells[orderNamesColumnIndex];

                    if (orderNamesCell.Value != null)
                    {
                        string cellValue = orderNamesCell.Value.ToString();
                        if (cellValue.Contains("已计费"))
                        {
                            // 使用浅绿颜色
                            row.DefaultCellStyle.BackColor = Color.LightGreen;
                        }
                        else if (cellValue.Contains("未计费"))
                        {
                            row.DefaultCellStyle.BackColor = Color.Red;
                        }
                        else if (cellValue.Contains("未开诊查费"))
                        {
                            row.DefaultCellStyle.BackColor = Color.Yellow;
                        }
                        else
                        {
                            // 恢复默认颜色
                            row.DefaultCellStyle.BackColor = SystemColors.Window;
                        }
                        
                        // 确保按钮列不受行颜色影响
                        if (dataGridView.Columns.Contains("colLisCount"))
                        {
                            int lisCountIndex = dataGridView.Columns["colLisCount"].Index;
                            if (row.Cells[lisCountIndex].Value != null && row.Cells[lisCountIndex].Value.ToString() != "0")
                            {
                                row.Cells[lisCountIndex].Style.BackColor = Color.MediumSpringGreen;
                            }
                        }
                        
                        if (dataGridView.Columns.Contains("colExamCount"))
                        {
                            int examCountIndex = dataGridView.Columns["colExamCount"].Index;
                            if (row.Cells[examCountIndex].Value != null && row.Cells[examCountIndex].Value.ToString() != "0")
                            {
                                row.Cells[examCountIndex].Style.BackColor = Color.PeachPuff;
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 加载医生患者记录数据
        /// </summary>
        private void LoadDoctorPatientRecords()
        {
            try
            {
                operateLog.WriteLog("开始加载医生患者记录数据...");
                
                if (userData == null)
                {
                    operateLog.WriteLog("userData为null，可能是因为没有通过登录流程启动程序");
                    return;
                }
                
                if (string.IsNullOrWhiteSpace(userData.user_id))
                {
                    operateLog.WriteLog("用户ID为空，无法获取医生患者记录");
                    return;
                }
                
                operateLog.WriteLog($"当前用户ID: {userData.user_id}");
                
                // 调用GetDoctorPatientRecords接口
                var response = PatientDataService.GetDoctorPatientRecords(userData.user_id);
                
                if (response != null && response.Success && response.Data != null && response.Data.Length > 0)
                {
                    operateLog.WriteLog($"获取到 {response.Data.Length} 条医生患者记录数据");
                    
                    // 将数据导入LocalData.xml
                    foreach (var patientData in response.Data)
                    {
                        try
                        {
                            // 构造与定时查询相同格式的JSON数据
                            var apiFormatData = new
                            {
                                success = true,
                                message = "数据获取成功",
                                data = new
                                {
                                    outP_VISIT_ID = patientData.OutpVisitId,
                                    patienT_ID = patientData.PatientId,
                                    patI_NAME = patientData.PatientName,
                                    outP_SPECIAL_NAME = patientData.OutpSpecialName,
                                    outP_DATE = patientData.OutpDate,
                                    visiT_ID = patientData.VisitId,
                                    admissioN_DOCTOR = patientData.AdmissionDoctor,
                                    doctoR_VS_OUTP_VISIT_ID = patientData.DoctorVsOutpVisitId,
                                    qR_CODE = patientData.QrCode,
                                    registratioN_FEE_STATUS = patientData.RegistrationFeeStatus,
                                    paT_LEVEL = patientData.PatLevel,
                                    liS_COUNT = patientData.LisCount,
                                    exaM_COUNT = patientData.ExamCount,
                                    reaD_FLAG = patientData.ReadFlag,
                                    ordeR_NAMES = patientData.OrderNames
                                }
                            };
                            
                            // 序列化为JSON字符串
                            string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(apiFormatData);
                            
                            // 保存到本地数据库
                            TimerTaskDataProcessor.ProcessPatientData(jsonData);
                        }
                        catch
                        {
                            operateLog.WriteLog($"处理患者数据失败，outP_VISIT_ID: {patientData.OutpVisitId}");
                        }
                    }
                    
                    // 刷新本地数据显示 - 确保在UI线程中执行
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new Action(() => LoadLocalData()));
                    }
                    else
                    {
                        LoadLocalData();
                    }
                    
                    operateLog.WriteLog("医生患者记录数据导入完成");
                }
                else
                {
                    string errorMsg = response?.Message ?? "未知错误";
                    operateLog.WriteLog($"获取医生患者记录失败: {errorMsg}");
                }
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("加载医生患者记录数据异常: " + ex.Message);
            }
        }

        /// <summary>
        /// 初始化定时器
        /// </summary>
        private void InitializeTimers()
        {
            try
            {
                // 初始化患者查询定时器 - 15秒间隔
                timerPatientQuery = new System.Windows.Forms.Timer();
                timerPatientQuery.Interval = 15000; // 15秒
                timerPatientQuery.Tick += timerPatientQuery_Tick;
                timerPatientQuery.Start();
                
                // 初始化数据刷新定时器 - 10分钟间隔
                timerDataRefresh = new System.Windows.Forms.Timer();
                timerDataRefresh.Interval = 600000; // 10分钟
                timerDataRefresh.Tick += timerDataRefresh_Tick;
                timerDataRefresh.Start();
                
                operateLog.WriteLog("定时器初始化完成 - 患者查询定时器: 15秒间隔, 数据刷新定时器: 10分钟间隔");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"定时器初始化失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 患者查询定时器事件处理
        /// </summary>
        private void timerPatientQuery_Tick(object sender, EventArgs e)
        {
            try
            {
                // 防重入：上一轮查询未结束则跳过本次
                if (isPatientQueryRunning)
                {
                    operateLog.WriteLog("定时查询跳过 - 上一次查询尚未完成");
                    return;
                }
                isPatientQueryRunning = true;
                // 在后台线程中执行患者数据查询，避免阻塞UI
                Thread queryThread = new Thread(() =>
                {
                    try
                    {
                        operateLog.WriteLog("定时查询患者数据开始...");
                        
                        if (userData != null && !string.IsNullOrWhiteSpace(userData.user_id))
                        {
                            // 调用GetDoctorPatientRecords接口获取最新数据
                            var response = PatientDataService.GetDoctorPatientRecords(userData.user_id);
                            
                            if (response != null && response.Success && response.Data != null && response.Data.Length > 0)
                            {
                                operateLog.WriteLog($"定时查询获取到 {response.Data.Length} 条患者数据");
                                
                                // 处理数据并更新本地数据库
                                foreach (var patientData in response.Data)
                                {
                                    try
                                    {
                                        // 构造API格式的JSON数据
                                        var apiFormatData = new
                                        {
                                            success = true,
                                            message = "数据获取成功",
                                            data = new
                                            {
                                                outP_VISIT_ID = patientData.OutpVisitId,
                                                patienT_ID = patientData.PatientId,
                                                patI_NAME = patientData.PatientName,
                                                outP_SPECIAL_NAME = patientData.OutpSpecialName,
                                                outP_DATE = patientData.OutpDate,
                                                visiT_ID = patientData.VisitId,
                                                admissioN_DOCTOR = patientData.AdmissionDoctor,
                                                doctoR_VS_OUTP_VISIT_ID = patientData.DoctorVsOutpVisitId,
                                                qR_CODE = patientData.QrCode,
                                                registratioN_FEE_STATUS = patientData.RegistrationFeeStatus,
                                                paT_LEVEL = patientData.PatLevel,
                                                liS_COUNT = patientData.LisCount,
                                                exaM_COUNT = patientData.ExamCount,
                                                reaD_FLAG = patientData.ReadFlag,
                                                ordeR_NAMES = patientData.OrderNames
                                            }
                                        };
                                        
                                        string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(apiFormatData);
                                        TimerTaskDataProcessor.ProcessPatientData(jsonData);
                                    }
                                    catch (Exception ex)
                                    {
                                        operateLog.WriteLog($"定时查询处理患者数据失败: {ex.Message}");
                                    }
                                }
                                
                                // 在UI线程中更新界面（使用BeginInvoke避免阻塞/重入问题）
                                SafeBeginInvoke(() =>
                                {
                                    LoadLocalData();
                                });
                                
                                operateLog.WriteLog("定时查询患者数据完成");
                            }
                            else
                            {
                                string errorMsg = response?.Message ?? "未知错误";
                                operateLog.WriteLog($"定时查询患者数据失败: {errorMsg}");
                            }
                        }
                        else
                        {
                            operateLog.WriteLog("定时查询跳过 - 用户信息无效");
                        }
                    }
                    catch (Exception ex)
                    {
                        operateLog.WriteLog($"定时查询患者数据异常: {ex.Message}");
                    }
                    finally
                    {
                        isPatientQueryRunning = false;
                    }
                })
                {
                    IsBackground = true
                };
                
                queryThread.Start();
            }
            catch (Exception ex)
            {
                isPatientQueryRunning = false;
                operateLog.WriteLog($"患者查询定时器事件处理异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 数据刷新定时器事件处理
        /// </summary>
        private void timerDataRefresh_Tick(object sender, EventArgs e)
        {
            try
            {
                // 防重入：上一轮刷新未结束则跳过本次
                if (isDataRefreshRunning)
                {
                    operateLog.WriteLog("定时数据刷新跳过 - 上一次刷新尚未完成");
                    return;
                }
                isDataRefreshRunning = true;
                // 在后台线程中执行数据刷新，避免阻塞UI
                Thread refreshThread = new Thread(() =>
                {
                    try
                    {
                        operateLog.WriteLog("定时数据刷新开始...");
                        
                        // 清空本地数据
                        LocalDbHelper.ClearAllData();
                        operateLog.WriteLog("本地数据已清空");
                        
                        // 重新加载数据
                        if (userData != null && !string.IsNullOrWhiteSpace(userData.user_id))
                        {
                            LoadDoctorPatientRecords();
                        }
                        
                        // 在UI线程中更新界面（使用BeginInvoke避免阻塞/重入问题）
                        SafeBeginInvoke(() =>
                        {
                            LoadLocalData();
                        });
                        
                        operateLog.WriteLog("定时数据刷新完成");
                    }
                    catch (Exception ex)
                    {
                        operateLog.WriteLog($"定时数据刷新异常: {ex.Message}");
                    }
                    finally
                    {
                        isDataRefreshRunning = false;
                    }
                })
                {
                    IsBackground = true
                };
                
                refreshThread.Start();
            }
            catch (Exception ex)
            {
                isDataRefreshRunning = false;
                operateLog.WriteLog($"数据刷新定时器事件处理异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 停止定时器
        /// </summary>
        private void StopTimers()
        {
            try
            {
                if (timerPatientQuery != null)
                {
                    timerPatientQuery.Stop();
                    timerPatientQuery.Dispose();
                    timerPatientQuery = null;
                }
                
                if (timerDataRefresh != null)
                {
                    timerDataRefresh.Stop();
                    timerDataRefresh.Dispose();
                    timerDataRefresh = null;
                }
                
                operateLog.WriteLog("定时器已停止");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"停止定时器异常: {ex.Message}");
            }
        }

        /// <summary>
        /// dgvLocalData的CellContentClick事件处理方法
        /// </summary>
        private void dgvLocalData_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dataGridView = (DataGridView)sender;
            if (e.RowIndex >= 0 && (dataGridView.Columns[e.ColumnIndex].Name == "colLisCount" || dataGridView.Columns[e.ColumnIndex].Name == "colExamCount"))
            {
                DataGridViewCell cell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
                if (cell.Value != null)
                {
                    string value = cell.Value.ToString();
                    if (value != "0")
                    {
                        // 获取选中行的数据
                        var selectedData = dgvLocalData.Rows[e.RowIndex].Tag as Dictionary<string, string>;
                        if (selectedData != null && selectedData.ContainsKey("doctoR_VS_OUTP_VISIT_ID"))
                        {
                            string idValue = selectedData["doctoR_VS_OUTP_VISIT_ID"].Split('&')[4];
                            // 在这里可以使用获取到的 id 值进行后续处理
                            string _url = ConfigurationManager.AppSettings["hisUrl"].ToString() + "His/getQueryUrl?query_id=" + idValue;
                            string _viewUrl = CodeHelper.HttpGetJson(_url);
                            //MessageBox.Show(_viewUrl);
                            string[] browserPaths = {
                                @"C:\Program Files\Google\Chrome\Application\chrome.exe",
                                @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
                                @"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
                                @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
                            };

                            string browserPath = null;
                            foreach (string path in browserPaths)
                            {
                                if (System.IO.File.Exists(path))
                                {
                                    browserPath = path;
                                    break;
                                }
                            }

                            if (browserPath != null)
                            {
                                System.Diagnostics.Process.Start(browserPath, _viewUrl);
                            }
                            else
                            {
                                // 如果没有找到浏览器，使用默认方式打开
                                System.Diagnostics.Process.Start(_viewUrl);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 处理DataGridView单元格点击事件
        /// </summary>
        private void dgvLocalData_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // 检查是否点击了查阅按钮列
                if (e.RowIndex >= 0 && e.ColumnIndex >= 0 &&
                    dgvLocalData.Columns[e.ColumnIndex].Name == "colViewButton")
                {
                    // 获取选中行的数据
                    var selectedData = dgvLocalData.Rows[e.RowIndex].Tag as Dictionary<string, string>;
                    if (selectedData != null)
                    {
                        // 显示详细信息
                        //ShowPatientDetails(selectedData);
                        // 设置QR_CODE到textBoxcx
                        SafeSetClipboardText(selectedData["qR_CODE"]);
                        //SetTextBoxcxValue(selectedData["qR_CODE"]);
                        tb_qrcode.Text = selectedData["qR_CODE"];
                        // 触发tb_qrcode控件的KeyDown事件
                        StartPatientQueryWithQr(tb_qrcode.Text, false);

                        // 重置所有复选框状态为未勾选
                        ResetAllCheckBoxes();

                        //QRBarCodePayRequest();
                        //SetBtLisExamStatus(selectedData["liS_COUNT"], selectedData["exaM_COUNT"], selectedData["doctoR_VS_OUTP_VISIT_ID"].Split('&')[4]);
                    }
                }
            }
            catch
            {
                MessageBox.Show("处理查阅操作失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 二维码/条码支付请求方法
        /// 注意：此方法包含许多变量，可能需要根据实际情况进行调整
        /// </summary>
        private void QRBarCodePayRequest()
        {
            try
            {
                // 初始化支付结果变量
                int QRBarCodePayRes = -999;
                string QRBarCodePayMsg = "";
                string DMFOutTradeNo = "";
                string _payCode = string.Empty;
                int _queryCount = 0;
                string payAmountText = "";

                // 在主线程上获取UI控件的值
                this.Invoke(new Action(() => {
                    textBoxFKM.Enabled = false;
                    _payCode = textBoxFKM.Text;
                    payAmountText = textBoxPayAmount.Text;
                }));

                // 生成订单号
                string OutTradeNo = "";
                ServiceRef.HospitalService_XXXXClient clientService = new ServiceRef.HospitalService_XXXXClient();
                ServiceRef.ResultBase reslut = clientService.GenerateSN();
                if (reslut != null)
                {
                    OutTradeNo = reslut.ReturnValue.ToString();
                    DMFOutTradeNo = OutTradeNo;
                    
                    // 更新UI显示订单号（如果OutTradeNo控件存在）
                    // this.BeginInvoke(new Action(() => this.OutTradeNo.Text = DMFOutTradeNo));
                }
                else
                {
                    QRBarCodePayRes = -1;
                    DMFOutTradeNo = "";
                    QRBarCodePayMsg = "获取流水号失败！";
                    // operateLog.WriteLog("获取订单号失败：" + reslut.Message);
                    
                    // 在主线程上更新UI
                    this.BeginInvoke(new Action(() => {
                        textBoxFKM.Enabled = true;
                        MessageBox.Show("获取流水号失败！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }));
                    return;
                }

                // 构建支付请求参数
                ServiceRef.QRBarPayInput requreInput = new ServiceRef.QRBarPayInput();
                requreInput.BarCode = _payCode;//textBoxFKM.Text; // 付款码
                requreInput.OutTradeNo = OutTradeNo; // 订单号
                requreInput.Body = "门诊充值";
                requreInput.Subject = "门诊充值";
                requreInput.TotalAmount = payAmountText; // 支付金额
                requreInput.FacePay = false;
                requreInput.Terminal = "001"; // 终端代码
                requreInput.PatientName = patinfo.PatientName;
                requreInput.IDCardNo = patinfo.PatientIDCardNO;
                requreInput.PatientID = patinfo.PatientID;
                requreInput.Operation = "门诊充值";
                requreInput.CardNo = patinfo.PatientID;
                requreInput.SellerName = "";
                //微信刷脸支付用参数
                requreInput.OpenId = "";
                requreInput.SubOpenId = "";
                // 检测支付类型（支付宝或微信）
                if (DetectPaymentType(_payCode) == "Alipay")
                {
                    requreInput.PayType = ServiceRef.EnumQRPay.alipay;
                }
                else
                {
                    requreInput.PayType = ServiceRef.EnumQRPay.weixin;
                }

                // 调用支付服务
                var sqlData = sqlServer.AddOrderMsg(patinfo.PatientID, patinfo.PatientName, patinfo.PatientIDCardNO, OutTradeNo, requreInput.TotalAmount, patinfo.CardNO, userData.user_id);
                var Str = sqlData;
                ServiceRef.QRBarPayOutput outputQRBarPayOutput = clientService.QRBarCodePayRequest(requreInput);

                if (outputQRBarPayOutput.Result == "0" && outputQRBarPayOutput.Result != null)
                {
                    // 支付请求成功，保存订单信息
                    // var sqlData = sqlServer.AddOrderMsg(patinfo.PatientID, patinfo.PatientName, patinfo.PatientIDCardNO, OutTradeNo, requreInput.TotalAmount, patinfo.CardNO, userData.user_id);

                    // operateLog.WriteLog("订单号：" + requreInput.OutTradeNo);

                    // 查询支付状态
                    ServiceRef.QRPayQueryInput requreQueryPayState = new ServiceRef.QRPayQueryInput();
                    requreQueryPayState.OutTradeNo = OutTradeNo;
                    requreQueryPayState.PayMoney = payAmountText;
                    requreQueryPayState.PayType = requreInput.PayType;
                    requreQueryPayState.TradeNo = "";
                    requreQueryPayState.Terminal = "001";
                    requreQueryPayState.FacePay = false;
                    _queryCount = Convert.ToInt32(ConfigurationManager.AppSettings["queryCount"].ToString());
                    for (int i = 1; i < _queryCount; i++)
                    {
                        ServiceRef.QRPayQueryOutput outputQueryState = clientService.QRPayQueryRequest(requreQueryPayState);
                        if (outputQueryState.Result != null && outputQueryState.Result == "0")
                        {
                            if (!string.IsNullOrEmpty(outputQueryState.OutTradeNo) && !string.IsNullOrEmpty(outputQueryState.TradeNo))
                            {
                                sqlServer.UpdateOrderMsg(patinfo.PatientID, requreInput.OutTradeNo, outputQueryState.TradeNo, getNowDateTime().ToString("yyyy-MM-dd HH:mm:ss"), "1", userData.user_id);
                                string Balance = "";
                                int res = deposit_userDeposit(outputQueryState, ref Balance);
                                if (res == 0)
                                {
                                    sqlServer.AddrechargeMsg(patinfo.PatientID, patinfo.PatientName, patinfo.PatientIDCardNO, requreInput.OutTradeNo, outputQueryState.TotalAmount, outputQueryState.TradeNo, userData.user_id);
                                    string IsPrint = ConfigurationManager.AppSettings["IsPrint"].ToString();
                                    if (IsPrint == "1")
                                    {
                                        PrintPt(outputQueryState.TotalAmount, outputQueryState.OutTradeNo, outputQueryState.TradeNo, outputQueryState.PaymentTime, Balance);
                                    }
                                    QRBarCodePayRes = 0;
                                    QRBarCodePayMsg = Balance;
                                    break;
                                }
                                else
                                {
                                    sqlServer.UpdateOrderMsg(patinfo.PatientID, requreInput.OutTradeNo, outputQueryState.TradeNo, getNowDateTime().ToString("yyyy-MM-dd HH:mm:ss"), "2", userData.user_id);

                                    QRBarCodePayMsg = "收款成功，但充值失败！";
                                    QRBarCodePayRes = -1;
                                    break;
                                }
                            }
                            else
                            {
                                QRBarCodePayMsg = "查询支付状态成功：未支付";
                                QRBarCodePayRes = -1;
                                Thread.Sleep(3000);
                            }
                        }
                        else
                        {
                            QRBarCodePayMsg = "状态查询失败！" + outputQueryState.Message;
                            QRBarCodePayRes = -1;
                            Thread.Sleep(3000);
                        }
                    }

                }
                else
                {
                    QRBarCodePayMsg = "付款码支付失败！" + outputQRBarPayOutput.Message;
                    QRBarCodePayRes = -1;
                }

                // 更新UI显示支付结果
                this.BeginInvoke(new Action(() => {
                    // 更新订单号显示（如果OutTradeNo控件存在）
                    // this.OutTradeNo.Text = DMFOutTradeNo;
                    
                    // 启用付款码输入框
                    textBoxFKM.Enabled = true;
                    
                    if (QRBarCodePayRes == 0)
                    {
                        // 支付成功
                        // 更新订单号显示（如果OutTradeNo控件存在）
                        // this.OutTradeNo.Text = DMFOutTradeNo;
                        string msg = "充值成功，余额：" + QRBarCodePayMsg;
                        ShowTransientCenterMessage(msg, 5000);
                        
                        // 清空支付金额和订单号
                        this.textBoxPayAmount.Text = "0";
                        this.textBoxPayAmount.ReadOnly = true;
                        // this.OutTradeNo.Text = "";
                        textBoxFKM.Text = "";
                        
                        // 重新查询患者信息，更新余额显示
                        StartPatientQueryWithQr(tb_qrcode.Text, false);
                    }
                    else
                    {
                        // 支付失败
                        MessageBox.Show(QRBarCodePayMsg, "支付失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }));
            }
            catch (Exception ex)
            {
                // operateLog.WriteLog("QRBarCodePayRequest异常：" + ex.Message);
                this.BeginInvoke(new Action(() => {
                    textBoxFKM.Enabled = true;
                    MessageBox.Show("支付处理异常：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }));
            }
        }

        /// <summary>
        /// 检测支付类型（支付宝或微信）
        /// </summary>
        /// <param name="paymentCode">付款码</param>
        /// <returns>支付类型：Alipay或Wechat</returns>
        public static string DetectPaymentType(string authCode)
        {
            int payType = int.Parse(authCode.Substring(0, 2));
            int length = authCode.Length;

            if (payType >= 10 && payType <= 15 && length == 18)
                return "WeChat";
            else if (payType >= 25 && payType <= 30 && length >= 16 && length <= 24)
                return "Alipay";
            else
                return "WeChat";
        }

        /// <summary>
        /// 打印收据方法
        /// 注意：此方法可能需要根据实际情况实现
        /// </summary>
        private void PrintPt(string totalAmount, string outTradeNo, string tradeNo, string paymentTime, string balance)
        {
            try
            {
                // TODO: 实现打印收据的逻辑
                // 这里需要根据Form1.cs中的PrintPt方法实现具体的打印功能
                operateLog.WriteLog("打印收据 - 金额：" + totalAmount + "，订单号：" + outTradeNo + "，交易号：" + tradeNo);
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("打印收据异常：" + ex.Message);
            }
        }

        /// <summary>
        /// 门诊充值
        /// </summary>
        /// <param name="outputQueryState"></param>
        /// <returns></returns>
        public int deposit_userDeposit(QRPayQueryOutput outputQueryState, ref string Balance)
        {
            try
            {
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();

                ServiceRef.DoPrepayIn inDeposit = new ServiceRef.DoPrepayIn();
                inDeposit.Key = "001";
                string Serial = "";
                ServiceRef.ResultBase reslut = new ServiceRef.ResultBase();
                reslut = clientService.GenerateSN();
                if (reslut != null)
                {
                    Serial = reslut.ReturnValue.ToString();
                }
                inDeposit.Serial = Serial;
                if (outputQueryState.TradeNo.Substring(0, 4) == "4200")
                {
                    inDeposit.PayMode = "7";
                }
                else
                {
                    inDeposit.PayMode = "6";
                }
                inDeposit.Amount = outputQueryState.TotalAmount; // PaymentAmount;
                inDeposit.CashCount = outputQueryState.TotalAmount; //
                #region 支付信息

                inDeposit.PayAccount = outputQueryState.TotalAmount; //PaymentAmount;
                inDeposit.PosSerial = outputQueryState.TradeNo;
                inDeposit.ReferenceNo = outputQueryState.OutTradeNo;
                #endregion
                //个人信息
                inDeposit.CardNO = patinfo.CardNO;
                inDeposit.PatientIDCardNo = patinfo.PatientName;
                inDeposit.PatientID = patinfo.PatientID;
                inDeposit.PatientName = patinfo.PatientIDCardNO;
                inDeposit.TerminalCode = "001";

                inDeposit.yqId = "";
                operateLog.WriteLog("充值执行开始");
                operateLog.WriteLog("操作员ID：" + userData.user_id);
                operateLog.WriteLog("操作员姓名：" + userData.user_name);
                operateLog.WriteLog("患者ID：" + patinfo.PatientID);
                operateLog.WriteLog("患者卡号：" + patinfo.CardNO);
                operateLog.WriteLog("患者姓名：" + patinfo.PatientName);
                operateLog.WriteLog("订单号：" + outputQueryState.TradeNo);
                operateLog.WriteLog("订单金额：" + outputQueryState.TotalAmount);
                operateLog.WriteLog("流水号：" + outputQueryState.OutTradeNo);

                #region //卡类型赋值
                inDeposit.CardTypeID = "1";
                #endregion

                //this.BeginSaveAction();
                ServiceRef.DoPrepayOut payrecArray = clientService.DoPrepay(inDeposit);

                if (payrecArray != null)
                {
                    if (payrecArray.Result == "0")
                    {
                        Balance = payrecArray.Balance;
                        return 0;
                    }
                    else
                    {
                        return -1;
                    }
                }
                else
                {
                    return -1;
                }
            }
            catch
            {
                return -2;
            }
        }

        private void textBoxFKM_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                try
                {
                    if (patinfo == null)
                    {
                        MessageBox.Show("请先查询病人信息再操作！");
                        return;
                    }

                    if (string.IsNullOrEmpty(this.textBoxPayAmount.Text))
                    {
                        MessageBox.Show("请输入充值金额！");
                        return;
                    }
                    if (string.IsNullOrEmpty(patinfo.PatientID))
                    {
                        MessageBox.Show("请先查询患者信息，再进行充值！");
                        return;
                    }
                    if (string.IsNullOrEmpty(textBoxFKM.Text))
                    {
                        MessageBox.Show("请让患者扫付款码！");
                        return;
                    }
                    if (Convert.ToDecimal(this.textBoxPayAmount.Text) <= 0)
                    {
                        MessageBox.Show("计算得到金额小于等于0，不允许充值！");
                        return;
                    }
                    //lblwaittip.Visible = false;
                    //this.pictureBox1.Visible = false;
                    //this.OutTradeNo.Text = "";
                    //cmd.ShowOpaqueLayer(this, 100, true);
                    threadQRBarCodePay = new Thread(QRBarCodePayRequest);
                    threadQRBarCodePay.Start(); // 直接传递参数给DoWork方法

                }
                catch
                {
                    MessageBox.Show("失败！异常");
                }
            }
        }

        private void textBoxPayAmount_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                // 回车后设置焦点到textBoxFKM并全选
                textBoxFKM.Focus();
                textBoxFKM.SelectAll();
                e.Handled = true; // 阻止默认的回车键行为
            }
            // 限制只能输入数字和小数点
            else if (!IsNumberKey(e.KeyCode) && e.KeyCode != Keys.Decimal && e.KeyCode != Keys.OemPeriod)
            {
                // 允许使用退格键、删除键、左右箭头键等
                if (e.KeyCode != Keys.Back && e.KeyCode != Keys.Delete && 
                    e.KeyCode != Keys.Left && e.KeyCode != Keys.Right && 
                    e.KeyCode != Keys.Home && e.KeyCode != Keys.End)
                {
                    e.Handled = true; // 阻止非数字键输入
                    e.SuppressKeyPress = true; // 阻止按键事件
                }
            }
        }

        /// <summary>
        /// 判断按键是否为数字键
        /// </summary>
        /// <param name="keyCode">按键码</param>
        /// <returns>是否为数字键</returns>
        private bool IsNumberKey(Keys keyCode)
        {
            // 0-9的按键码
            return (keyCode >= Keys.D0 && keyCode <= Keys.D9) || 
                   (keyCode >= Keys.NumPad0 && keyCode <= Keys.NumPad9);
        }
        
        /// <summary>
        /// 显示本机IP地址
        /// </summary>
        public void DisplayIPAddress()
        {
            try
            {
                operateLog.WriteLog("开始获取本机IP地址");
                string ipAddress = "";
                
                // 方法1：尝试获取所有网络接口的IP地址
                try
                {
                    operateLog.WriteLog("尝试通过网络接口获取IP地址");
                    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
                    {
                        if (ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet || 
                            ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
                        {
                            if (ni.OperationalStatus == OperationalStatus.Up)
                            {
                                IPInterfaceProperties ipProps = ni.GetIPProperties();
                                foreach (UnicastIPAddressInformation ip in ipProps.UnicastAddresses)
                                {
                                    if (ip.Address.AddressFamily == AddressFamily.InterNetwork && 
                                        !IPAddress.IsLoopback(ip.Address))
                                    {
                                        ipAddress = ip.Address.ToString();
                                        operateLog.WriteLog($"找到IP地址: {ipAddress}, 网络接口: {ni.Name}, 类型: {ni.NetworkInterfaceType}");
                                        // 如果找到以太网连接的IP，优先使用
                                        if (ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                                        {
                                            break;
                                        }
                                    }
                                }
                                if (!string.IsNullOrEmpty(ipAddress) && 
                                    ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    operateLog.WriteLog($"通过网络接口获取IP地址失败: {ex.Message}");
                    // 如果上述方法失败，回退到原始方法
                    try
                    {
                        operateLog.WriteLog("尝试通过DNS获取IP地址");
                        string hostName = Dns.GetHostName();
                        IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
                        
                        foreach (IPAddress ip in hostEntry.AddressList)
                        {
                            if (ip.AddressFamily == AddressFamily.InterNetwork && 
                                !IPAddress.IsLoopback(ip))
                            {
                                ipAddress = ip.ToString();
                                operateLog.WriteLog($"通过DNS找到IP地址: {ipAddress}");
                                break;
                            }
                        }
                    }
                    catch (Exception dnsEx)
                    {
                        operateLog.WriteLog($"通过DNS获取IP地址也失败: {dnsEx.Message}");
                    }
                }

                // 更新LB_IP控件的Text属性
                if (LB_IP != null)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                        LB_IP.Text = "本机IP:" + ipAddress;
                        operateLog.WriteLog($"成功更新IP地址显示: {ipAddress}");
                    }));
                }
                else
                {
                    operateLog.WriteLog("LB_IP控件为null，无法更新IP地址显示");
                }
            }
            catch (SocketException ex)
            {
                // 记录具体错误信息，便于调试
                operateLog.WriteLog("获取IP地址时发生套接字错误: " + ex.Message);
                
                // 更新LB_IP控件显示错误信息
                if (LB_IP != null)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                        LB_IP.Text = "本机IP:获取失败";
                    }));
                }
            }
            catch (Exception ex)
            {
                // 记录具体错误信息，便于调试
                operateLog.WriteLog("获取IP地址时发生未知错误: " + ex.Message);
                
                // 更新LB_IP控件显示错误信息
                if (LB_IP != null)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                        LB_IP.Text = "本机IP:获取失败";
                    }));
                }
            }
        }

        private void BT_QUERYORDER_Click(object sender, EventArgs e)
        {
            PayMsg from = new PayMsg(userData);
            from.ShowDialog();
        }
        #region 医保电子支付
        /// <summary>
        /// 待缴费明细列表
        /// </summary>
        public List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem> payDetailList = new List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem>();

        [DllImport("NationECCode.dll", EntryPoint = "NationEcTrans")]
        public static extern IntPtr NationEcTrans(StringBuilder strUrl, StringBuilder InData, StringBuilder OutData);

        private string card_code = "";
        private string userInf = "";
        private string ListStr = "";
        private QueryPrePaymentCostOut payres;
        private void btnYbPay_Click(object sender, EventArgs e)
        {
            try
            {
                payDetailList = new List<BMS_ORDERS_BILL_DETAILChargeItemItem>();
                payres = new QueryPrePaymentCostOut();
                card_code = "";
                userInf = "";

                //if (string.IsNullOrEmpty(this.labelhzid.Text))
                //{
                //    MessageBox.Show("请先查询患者信息，再进行充值！");
                //    return;
                //}
                if (string.IsNullOrEmpty(patinfo.PatientID))
                {
                    MessageBox.Show("请先查询患者信息，再进行充值！");
                    return;
                }
                //if (string.IsNullOrEmpty(this.labelName.Text))
                //{
                //    MessageBox.Show("请先查询患者信息，再进行充值！");
                //    return;
                //}

                var data = new
                {
                    data = new
                    {
                        operatorId = "ZJ01",
                        operatorName = "自助机Z001",
                        officeId = "01",
                        officeName = "内科",
                        orgId = "H45020200060",
                        businessType = "01301",
                        deviceType = ""
                    },
                    orgId = "H45112100058",
                    transType = "ec.query"
                };
                StringBuilder ptrUrl = new StringBuilder();
                StringBuilder ptrSendInfo = new StringBuilder();
                ptrSendInfo.Append(Newtonsoft.Json.JsonConvert.SerializeObject(data));
                StringBuilder OutData = new StringBuilder(8000 + 1);
                ptrUrl.Append("http://59.211.232.33:10110/localcfc/api/hsecfc/localQrCodeQuery");
                NationEcTrans(ptrUrl, ptrSendInfo, OutData);
                string ectrans = OutData.ToString();
                card_code = ectrans;
                var OutDataModel = Newtonsoft.Json.JsonConvert.DeserializeObject<MedicalVoucherRoot>(ectrans);
                if (OutDataModel.code == "0")
                {
                    #region 获取参保信息
                    ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                    var cardInfoIn = new ServiceRef.kite_aio_In();
                    cardInfoIn.cardInfo = "";
                    cardInfoIn.medicareType = "1";
                    cardInfoIn.socialsecurityNo = "";
                    cardInfoIn.card_id = "";
                    cardInfoIn.card_code = ectrans;
                    cardInfoIn.yqId = "";
                    cardInfoIn.terminalCode = "001";
                    cardInfoIn.PatientID = patinfo.PatientID;
                    var result = clientService.kite_aio_co3(cardInfoIn);
                    if (result.Result == "00")
                    {
                        if (result.idCardCode != patinfo.PatientIDCardNO)
                        {
                            MessageBox.Show("当前患者身份证号：" + patinfo.PatientIDCardNO + ",与医保电子凭证参保信息身份证号" + result.idCardCode + "不一致，请使用患者本人医保电子凭证结算！");
                            return;
                        }
                        userInf = result.data;
                        if (IsSelect == "1")
                        {
                            #region 进行预结算
                            QueryPrePaymentCostIn inDoPrePay = new QueryPrePaymentCostIn();
                            inDoPrePay.TerminalCode = "001";
                            inDoPrePay.PatientID = patinfo.PatientID;
                            inDoPrePay.PayType = "1";
                            inDoPrePay.yqId = "LZ001";


                            inDoPrePay.ChargeItem = new List<BMS_ORDERS_BILL_DETAILChargeItemItem>();


                            decimal ToMoney = 0;
                            for (int i = 0; i < dgv_master.Rows.Count; i++)
                            {
                                var boolStr = dgv_master.Rows[i].Cells["ColumnSelect"].Value.ToString();
                                if (boolStr == "True")
                                {
                                    //item.Cells["处方号"].Value.ToString();
                                    ToMoney += Convert.ToDecimal(dgv_master.Rows[i].Cells["金额"].Value.ToString());
                                    dgv_master.Rows[i].DefaultCellStyle.ForeColor = Color.Red;
                                    ListStr += dgv_master.Rows[i].Cells["apply_master"].Value.ToString() + ",";

                                    var listdel = PayDetail.First(x => x.Key == dgv_master.Rows[i].Cells["apply_master"].Value.ToString());
                                    foreach (var item2 in listdel.Value)
                                    {
                                        ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem ChargeItemItem = new ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem();
                                        #region 柳州妇幼
                                        ChargeItemItem.ItemId = item2.ItemId;
                                        ChargeItemItem.PatientVisitId = dgv_master.Rows[i].Cells["就诊流水号"].Value.ToString();
                                        ChargeItemItem.ClinicItemCode = item2.ClinicItemCode;
                                        ChargeItemItem.SpellCode = item2.SpellCode;
                                        ChargeItemItem.ClinicId = item2.ClinicId;
                                        ChargeItemItem.OrderDate = item2.OrderDate;
                                        ChargeItemItem.OrderBeginDate = item2.OrderBeginDate;
                                        ChargeItemItem.MipsEmpIdBegDoct = item2.MipsEmpIdBegDoct;
                                        ChargeItemItem.DiagIcd = item2.DiagIcd;
                                        ChargeItemItem.DiagName = item2.DiagName;
                                        ChargeItemItem.Diags = item2.Diags;

                                        ChargeItemItem.ItemClass = item2.ItemClass;
                                        ChargeItemItem.ItemClassName = item2.ItemClassName;
                                        ChargeItemItem.ItemCode = item2.ItemCode;
                                        ChargeItemItem.ItemName = item2.ItemName;
                                        ChargeItemItem.Spec = item2.Spec;
                                        ChargeItemItem.Amount = item2.Amount;
                                        ChargeItemItem.VisitId = item2.VisitId;
                                        ChargeItemItem.PatientId = item2.PatientId;
                                        ChargeItemItem.Price = item2.Price;
                                        ChargeItemItem.SalesPrice = item2.SalesPrice;
                                        ChargeItemItem.Costs = item2.Costs;
                                        ChargeItemItem.Charges = item2.Charges;
                                        ChargeItemItem.ApplyId = item2.ApplyId;
                                        ChargeItemItem.OrderByDeptCode = item2.OrderByDeptCode;
                                        ChargeItemItem.OrderByDeptName = item2.OrderByDeptName;
                                        ChargeItemItem.PerformedByDeptCode = item2.PerformedByDeptCode;
                                        ChargeItemItem.PerformedByDeptName = item2.PerformedByDeptName;
                                        ChargeItemItem.DiagEmpId = item2.DiagEmpId;
                                        ChargeItemItem.DiagEmpName = item2.DiagEmpName;
                                        ChargeItemItem.DiagByCode = item2.DiagByCode;
                                        ChargeItemItem.InsuranceType = item2.InsuranceType;
                                        ChargeItemItem.InsurLevelCode = item2.InsurLevelCode;
                                        ChargeItemItem.InsurLevelName = item2.InsurLevelName;
                                        ChargeItemItem.ChargeDate = item2.ChargeDate;
                                        ChargeItemItem.OrgIdHospital = item2.OrgIdHospital;
                                        ChargeItemItem.EnterDate = item2.EnterDate;
                                        ChargeItemItem.InvoicePrintStatus = item2.InvoicePrintStatus;
                                        ChargeItemItem.SubjCode = item2.SubjCode;
                                        ChargeItemItem.UnitName = item2.UnitName;
                                        ChargeItemItem.Factor = item2.Factor;
                                        ChargeItemItem.RetailFactor = item2.RetailFactor;
                                        ChargeItemItem.Quantity = item2.Quantity;
                                        ChargeItemItem.UnitQuantity = item2.UnitQuantity;
                                        ChargeItemItem.InClassOnRcptCode = item2.InClassOnRcptCode;
                                        ChargeItemItem.InClassOnRcptCodeName = item2.InClassOnRcptCodeName;
                                        ChargeItemItem.OutClassOnRcptCode = item2.OutClassOnRcptCode;
                                        ChargeItemItem.OutClassOnRcptCodeName = item2.OutClassOnRcptCodeName;
                                        ChargeItemItem.ApplyClass = item2.ApplyClass;
                                        ChargeItemItem.ApplyClassName = item2.ApplyClassName;
                                        ChargeItemItem.Ratio = item2.Ratio;
                                        ChargeItemItem.AutoRatio = item2.AutoRatio;
                                        ChargeItemItem.ChargedStatus = item2.ChargedStatus;
                                        ChargeItemItem.OrderId = item2.OrderId;
                                        ChargeItemItem.OrderItemDetailId = item2.OrderItemDetailId;
                                        ChargeItemItem.CurrentNursingUnit = item2.CurrentNursingUnit;
                                        ChargeItemItem.ExternalId = item2.ExternalId;
                                        ChargeItemItem.IsCharge = item2.IsCharge;
                                        ChargeItemItem.InOutFlag = item2.InOutFlag;
                                        ChargeItemItem.PerMed = item2.PerMed;
                                        ChargeItemItem.FreqName = item2.FreqName;
                                        ChargeItemItem.Duration = item2.Duration;
                                        ChargeItemItem.MedUnitName = item2.MedUnitName;
                                        ChargeItemItem.FreqUnitName = item2.FreqUnitName;
                                        ChargeItemItem.DurationUnitName = item2.DurationUnitName;
                                        #endregion
                                        inDoPrePay.ChargeItem.Add(ChargeItemItem);

                                        payDetailList.Add(ChargeItemItem);
                                    }

                                }
                                else
                                {
                                    dgv_master.Rows[i].DefaultCellStyle.ForeColor = Color.Black;
                                }
                            }

                            #endregion
                            if (payDetailList != null && payDetailList.Count > 0)
                            {
                                inDoPrePay.RecipeNO = ListStr.Substring(0, ListStr.Length - 1);

                                inDoPrePay.cardInfo = "";
                                inDoPrePay.medicareType = "2";
                                inDoPrePay.totalMoney = ToMoney.ToString();
                                inDoPrePay.uerInfo = result.data;
                                inDoPrePay.extend = ectrans;
                                payres = clientService.QueryPrePaymentCost(inDoPrePay);
                                if (payres != null)
                                {
                                    if (payres.Result == "0")
                                    {
                                        YbPrePay from = new YbPrePay(payres, patinfo, result.medicalBanlance);
                                        from.Closed += new EventHandler(frmPrePay_Closed);
                                        from.ShowDialog();

                                    }
                                    else if (payres.Result == "-1")
                                    {
                                        MessageBox.Show(payres.Message);
                                        return;
                                    }
                                    else if (payres.Result == "-3" || payres.Message.IndexOf("key为空") != -1)
                                    {

                                        MessageBox.Show("key为空!" + payres.Message);
                                        return;
                                    }
                                    else
                                    {
                                        MessageBox.Show(payres.Message);
                                        return;
                                    }
                                }
                                else
                                {
                                    MessageBox.Show("预结算失败，出参数据为空。");
                                    return;
                                }
                            }
                            else
                            {
                                MessageBox.Show("请选择需要计算的处方。");
                            }

                        }
                        else
                        {
                            MessageBox.Show("请选择需要计算的处方。");
                        }


                    }
                    else
                    {
                        MessageBox.Show("医保电子凭证解码失败！" + OutDataModel.message);
                        return;
                    }

                    #endregion

                }
                else
                {
                    MessageBox.Show("医保电子凭证解码失败！" + OutDataModel.message);
                    return;
                }
            }
            catch
            {
                MessageBox.Show("医保电子凭证解码异常！");
            }
        }

        private void frmPrePay_Closed(object sender, EventArgs e)
        {
            ServiceRef.DoPayOut payresdata = new DoPayOut();
            string msg = "";
            YbPrePay frm = (YbPrePay)sender;
            if (frm.IsJs)//余额充足，直接结算
            {
                int res = pay_userPay(payres, frm.bsje, frm.fkm, ref payresdata, ref msg);
                if (res == 0)
                {
                    MessageBox.Show("结算成功！");
                }
                else
                {
                    MessageBox.Show(msg);
                }

            }
            else
            {
                cmd.ShowOpaqueLayer(this, 100, true);
                new Thread(() =>
                {
                    QRBarCodePayRequestYB(payres, frm.bsje, frm.fkm); //处理事件
                }).Start(); //启动线程
            }
        }

        /// <summary>
        /// 结算his
        /// </summary>
        /// <returns></returns>
        private int pay_userPay(QueryPrePaymentCostOut payres2, string bsje, string fkm, ref ServiceRef.DoPayOut payresdata, ref string msg)
        {
            int res = -1;
            try
            {
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                ServiceRef.DoPayIn inDoPay = new ServiceRef.DoPayIn();
                inDoPay.CardTypeID = "1";
                inDoPay.PayAmount = payres2.PayAmount;
                #region 支付信息
                var list = new List<ServiceRef.DoPayInItem>();
                //医保卡赋值
                //inDoPay.PactFundAmount = payres2.PactFundAmount;
                //inDoPay.PactSelfAmount = payres2.PactSelfAmount;
                inDoPay.PactNO = "";

                {
                    ServiceRef.DoPayInItem item = new ServiceRef.DoPayInItem();
                    item.PayAmount = payres2.PayAmount;
                    item.PayCardNO = "";
                    item.PayTypeID = "5";// inParam.inPayInfo.type.ToString();
                    item.PayNote = "无";
                    item.PayModeName = "医保卡";
                    list.Add(item);
                }
                //诊疗卡赋值
                if (Convert.ToDecimal(bsje) == 0)
                {
                    ServiceRef.DoPayInItem item = new ServiceRef.DoPayInItem();
                    item.PayAmount = payres2.SelfPayAmount;
                    item.PayTypeID = "2";//inParam.inPayInfo.type.ToString();
                    item.PayNote = "无";
                    item.PayModeName = "就诊卡";
                    list.Add(item);
                }

                //微信赋值
                if (Convert.ToDecimal(bsje) > 0)
                {
                    ServiceRef.DoPayInItem item = new ServiceRef.DoPayInItem();
                    item.PayAmount = bsje;
                    item.PayCardNO = "";
                    item.PayNo = fkm;
                    item.PayTypeID = "7";//inParam.inPayInfo.type.ToString();
                    item.OutTradeNo = fkm;
                    item.TradeNo = fkm;
                    item.PayNote = "无";
                    item.PayModeName = "微信";
                    list.Add(item);
                }

                #endregion

                inDoPay.PatientID = patinfo.PatientID;
                inDoPay.CardNO = patinfo.CardNO;
                inDoPay.PatientIDCardNo = patinfo.PatientIDCardNO;
                inDoPay.PatientName = patinfo.PatientName;
                inDoPay.PatientCardPassword = "";
                inDoPay.InvoiceNo = "";
                inDoPay.ShouldPay = payres2.PayAmount;//SystemStaticData.tmpPay.payPrescriptionList[0].totalMoney;
                inDoPay.PactFundAmount = payres2.PactFundAmount;
                inDoPay.PactSelfAmount = payres2.PactSelfAmount;
                inDoPay.SelfPayAmount = payres2.SelfPayAmount;


                inDoPay.treatId = payres2.treatId;
                inDoPay.xmlInputText = payres2.InputVisitText;

                inDoPay.extend = card_code ?? "";
                inDoPay.medicareType = "2";
                inDoPay.cardinfo = "";
                inDoPay.uerInfo = userInf ?? "";

                //inDoPay.cardinfo = "B32601150|450200D156000005A601EDA21F4037D9|3|2.0|450200|20161130|FFFFFFFF|421023199310197158|易博文|NEW|";

                inDoPay.ChargeItem = new List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem>();
                inDoPay.yqId = "LZ001";

                inDoPay.ChargeTypeCode = "";// SystemStaticData.tmpPay.payPrescriptionList[0].FYLXDH;//item.FYLXDH;

                //foreach (var item2 in item.payDetailList)
                foreach (var item2 in payDetailList)
                {
                    ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem ChargeItemItem = new ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem();
                    #region 柳州妇幼
                    ChargeItemItem.ItemId = item2.ItemId;
                    ChargeItemItem.ClinicItemCode = item2.ClinicItemCode;
                    ChargeItemItem.PatientVisitId = item2.PatientVisitId;
                    ChargeItemItem.SpellCode = item2.SpellCode;
                    ChargeItemItem.ClinicId = item2.ClinicId;
                    ChargeItemItem.OrderDate = item2.OrderDate;
                    ChargeItemItem.OrderBeginDate = item2.OrderBeginDate;
                    ChargeItemItem.MipsEmpIdBegDoct = item2.MipsEmpIdBegDoct;
                    ChargeItemItem.DiagIcd = item2.DiagIcd;
                    ChargeItemItem.DiagName = item2.DiagName;
                    ChargeItemItem.Diags = item2.Diags;

                    ChargeItemItem.ItemClass = item2.ItemClass;
                    ChargeItemItem.ItemClassName = item2.ItemClassName;
                    ChargeItemItem.ItemCode = item2.ItemCode;
                    ChargeItemItem.ItemName = item2.ItemName;
                    ChargeItemItem.Spec = item2.Spec;
                    ChargeItemItem.Amount = item2.Amount;
                    ChargeItemItem.VisitId = item2.VisitId;
                    ChargeItemItem.PatientId = item2.PatientId;
                    ChargeItemItem.Price = item2.Price;
                    ChargeItemItem.SalesPrice = item2.SalesPrice;
                    ChargeItemItem.Costs = item2.Costs;
                    ChargeItemItem.Charges = item2.Charges;
                    ChargeItemItem.ApplyId = item2.ApplyId;
                    ChargeItemItem.OrderByDeptCode = item2.OrderByDeptCode;
                    ChargeItemItem.OrderByDeptName = item2.OrderByDeptName;
                    ChargeItemItem.PerformedByDeptCode = item2.PerformedByDeptCode;
                    ChargeItemItem.PerformedByDeptName = item2.PerformedByDeptName;
                    ChargeItemItem.DiagEmpId = item2.DiagEmpId;
                    ChargeItemItem.DiagEmpName = item2.DiagEmpName;
                    ChargeItemItem.DiagByCode = item2.DiagByCode;
                    ChargeItemItem.InsuranceType = item2.InsuranceType;
                    ChargeItemItem.InsurLevelCode = item2.InsurLevelCode;
                    ChargeItemItem.InsurLevelName = item2.InsurLevelName;
                    ChargeItemItem.ChargeDate = item2.ChargeDate;
                    ChargeItemItem.OrgIdHospital = item2.OrgIdHospital;
                    ChargeItemItem.EnterDate = item2.EnterDate;
                    ChargeItemItem.InvoicePrintStatus = item2.InvoicePrintStatus;
                    ChargeItemItem.SubjCode = item2.SubjCode;
                    ChargeItemItem.UnitName = item2.UnitName;
                    ChargeItemItem.Factor = item2.Factor;
                    ChargeItemItem.RetailFactor = item2.RetailFactor;
                    ChargeItemItem.Quantity = item2.Quantity;
                    ChargeItemItem.UnitQuantity = item2.UnitQuantity;
                    ChargeItemItem.InClassOnRcptCode = item2.InClassOnRcptCode;
                    ChargeItemItem.InClassOnRcptCodeName = item2.InClassOnRcptCodeName;
                    ChargeItemItem.OutClassOnRcptCode = item2.OutClassOnRcptCode;
                    ChargeItemItem.OutClassOnRcptCodeName = item2.OutClassOnRcptCodeName;
                    ChargeItemItem.ApplyClass = item2.ApplyClass;
                    ChargeItemItem.ApplyClassName = item2.ApplyClassName;
                    ChargeItemItem.Ratio = item2.Ratio;
                    ChargeItemItem.AutoRatio = item2.AutoRatio;
                    ChargeItemItem.ChargedStatus = item2.ChargedStatus;
                    ChargeItemItem.OrderId = item2.OrderId;
                    ChargeItemItem.OrderItemDetailId = item2.OrderItemDetailId;
                    ChargeItemItem.CurrentNursingUnit = item2.CurrentNursingUnit;
                    ChargeItemItem.ExternalId = item2.ExternalId;
                    ChargeItemItem.IsCharge = item2.IsCharge;
                    ChargeItemItem.InOutFlag = item2.InOutFlag;
                    ChargeItemItem.PerMed = item2.PerMed;
                    ChargeItemItem.FreqName = item2.FreqName;
                    ChargeItemItem.Duration = item2.Duration;
                    ChargeItemItem.MedUnitName = item2.MedUnitName;
                    ChargeItemItem.FreqUnitName = item2.FreqUnitName;
                    ChargeItemItem.DurationUnitName = item2.DurationUnitName;
                    #endregion
                    inDoPay.ChargeItem.Add(ChargeItemItem);
                }

                inDoPay.RegFlow = ListStr.Substring(0, ListStr.Length - 1); ;

                //inDoPay.RegFlow = SystemStaticData.tmpPay.payPrescriptionList[0].prescriptionNo;
                inDoPay.Serial = DateTime.Now.ToString("yyyyMMddHHmmss");
                inDoPay.TerminalCode = "001";
                inDoPay.Key = "001";
                inDoPay.list = list;
                //this.BeginSaveAction();
                // 记录DoPay调用的入参JSON日志
                //operateLog.WriteLog("DoPay调用入参：" + Newtonsoft.Json.JsonConvert.SerializeObject(inDoPay));
                payresdata = clientService.DoPay(inDoPay);
                // 记录DoPay调用的返回值JSON日志
                //operateLog.WriteLog("DoPay调用返回值：" + Newtonsoft.Json.JsonConvert.SerializeObject(payresdata));

                if (payres != null)
                {
                    if (payres.Result == "0")
                    {
                        //this.EndSaveAction();
                        //outParam.outPayRes.sn = payres.TranFlow;
                        //outParam.outPayRes.invoiceNo = payres.TranFlow;
                        //outParam.outPayRes.drugWindows = payres.DrugWindows;
                        //outParam.outPayRes.updateTime = payres.TranTime;
                        //outParam.inPerson.banlance = payres.Balance;

                        res = 0;

                    }
                    else if (payres.Result == "-1")
                    {
                        msg = "结算失败！" + payres.Message;
                        res = -1;
                    }
                    else if (payres.Result == "-3" || payres.Message.IndexOf("key为空") != -1)
                    {
                        msg = "结算失败！key为空！" + payres.Message;
                        res = -2;
                    }
                    else
                    {
                        msg = "结算失败！" + payres.Message;
                        res = -2;
                    }
                }
                else
                {
                    msg = "结算失败！出参信息为空！";
                    res = -2;
                }
            }
            catch
            {
                msg = "结算his异常";
                res = -2;
            }

            return res;
        }

        #endregion

        #region QRBarCodePayRequest2函数
        /// <summary>
        /// QRBarCodePayRequest2委托定义
        /// </summary>
        public delegate void FormShowQRBarCodePay2();
        public FormShowQRBarCodePay2 invokeQRBarCodePay2;

        /// <summary>
        /// QRBarCodePayRequest2函数实现
        /// </summary>
        /// <param name="payres2">预结算结果</param>
        /// <param name="bsje">补交金额</param>
        /// <param name="fkm">付款码</param>
        void QRBarCodePayRequestYB(QueryPrePaymentCostOut payres2, string bsje, string fkm)
        {
            QRBarCodePayRes = -999;
            DMFOutTradeNo = "";
            ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
            string OutTradeNo = "";
            ServiceRef.ResultBase reslut = new ServiceRef.ResultBase();
            reslut = clientService.GenerateSN();
            if (reslut != null)
            {
                OutTradeNo = reslut.ReturnValue.ToString();
                DMFOutTradeNo = OutTradeNo;
                QRBarPayInput requreInput = new QRBarPayInput()
                {
                    BarCode = fkm,
                    OutTradeNo = OutTradeNo,
                    Body = "门诊充值",
                    Subject = "门诊充值",
                    //operatorId = InParam.operatorId,
                    TotalAmount = bsje,
                    FacePay = false,

                    Terminal = "001",
                    PatientName = patinfo.PatientName,
                    IDCardNo = patinfo.PatientIDCardNO,
                    PatientID = patinfo.PatientID,
                    Operation = "门诊充值",
                    CardNo = patinfo.PatientID,
                    SellerName = "",

                    //微信刷脸支付用参数
                    OpenId = "",
                    SubOpenId = "",
                };
                if (DetectPaymentType(fkm) == "Alipay")
                {
                    requreInput.PayType = EnumQRPay.alipay;
                }
                else
                {
                    requreInput.PayType = EnumQRPay.weixin;
                }
                outputQRBarPayOutput = new QRBarPayOutput();
                var sqlData = sqlServer.AddOrderMsg(patinfo.PatientID, patinfo.PatientName, patinfo.PatientIDCardNO, OutTradeNo, requreInput.TotalAmount, patinfo.CardNO, userData.user_id);
                var Str = sqlData;

                //operateLog.WriteLog("付款码支付开始");
                //operateLog.WriteLog("操作员ID：" + userData.user_id);
                //operateLog.WriteLog("操作员姓名：" + userData.user_name);
                //operateLog.WriteLog("患者ID：" + patinfo.PatientID);
                //operateLog.WriteLog("患者卡号：" + patinfo.CardNO);
                //operateLog.WriteLog("患者姓名：" + patinfo.PatientName);
                //operateLog.WriteLog("订单号：" + requreInput.OutTradeNo);
                //operateLog.WriteLog("订单金额：" + requreInput.TotalAmount);

                outputQRBarPayOutput = clientService.QRBarCodePayRequest(requreInput);

                if (outputQRBarPayOutput.Result != null && outputQRBarPayOutput.Result == "0")
                {
                    int queryCount = Convert.ToInt32(ConfigurationManager.AppSettings["queryCount"].ToString());
                    for (int i = 0; i < queryCount; i++)
                    {
                        QRPayQueryInput requreQueryPayState = new QRPayQueryInput();
                        requreQueryPayState.OutTradeNo = OutTradeNo;
                        requreQueryPayState.TradeNo = "";
                        requreQueryPayState.PayMoney = textBoxPayAmount.Text;
                        requreQueryPayState.Terminal = "001";
                        requreQueryPayState.FacePay = false;
                        //requreQueryPayState.PayType = EnumQRPay.weixin;
                        if (DetectPaymentType(fkm) == "Alipay")
                        {
                            requreQueryPayState.PayType = EnumQRPay.alipay;
                        }
                        else
                        {
                            requreQueryPayState.PayType = EnumQRPay.weixin;
                        }
                        QRPayQueryOutput outputQueryState = clientService.QRPayQueryRequest(requreQueryPayState);
                        if (outputQueryState.Result != null && outputQueryState.Result == "0")
                        {
                            if (!string.IsNullOrEmpty(outputQueryState.OutTradeNo) && !string.IsNullOrEmpty(outputQueryState.TradeNo))
                            {
                                sqlServer.UpdateOrderMsg(patinfo.PatientID, requreInput.OutTradeNo, outputQueryState.TradeNo, getNowDateTime().ToString("yyyy-MM-dd HH:mm:ss"), "1", userData.user_id);
                                string Balance = "";
                                int res = deposit_userDeposit(outputQueryState, ref Balance);
                                if (res == 0)
                                {
                                    sqlServer.AddrechargeMsg(patinfo.PatientID, patinfo.PatientName, patinfo.PatientIDCardNO, requreInput.OutTradeNo, outputQueryState.TotalAmount, outputQueryState.TradeNo, userData.user_id);
                                    string IsPrint = ConfigurationManager.AppSettings["IsPrint"].ToString();
                                    if (IsPrint == "1")
                                    {
                                        PrintPt(outputQueryState.TotalAmount, outputQueryState.OutTradeNo, outputQueryState.TradeNo, outputQueryState.PaymentTime, Balance);
                                    }
                                    QRBarCodePayRes = 0;
                                    QRBarCodePayMsg = Balance;

                                    ServiceRef.DoPayOut payresdata = new DoPayOut();
                                    string msg = "";
                                    res = pay_userPay(payres2, bsje, fkm, ref payresdata, ref msg);
                                    if (res == 0)
                                    {
                                        QRBarCodePayRes = 0;
                                        QRBarCodePayMsg = Balance;
                                    }
                                    else
                                    {
                                        QRBarCodePayRes = -2;
                                        QRBarCodePayMsg = msg;
                                    }
                                    break;
                                }
                                else
                                {
                                    sqlServer.UpdateOrderMsg(patinfo.PatientID, requreInput.OutTradeNo, outputQueryState.TradeNo, getNowDateTime().ToString("yyyy-MM-dd HH:mm:ss"), "2", userData.user_id);

                                    QRBarCodePayMsg = "收款成功，但充值失败！";
                                    QRBarCodePayRes = -1;
                                    break;
                                }

                            }
                            else
                            {
                                QRBarCodePayMsg = "查询支付状态成功：未支付";
                                QRBarCodePayRes = -1;
                                Thread.Sleep(3000);
                            }
                        }
                        else
                        {
                            QRBarCodePayMsg = "状态查询失败！" + outputQueryState.Message;
                            QRBarCodePayRes = -1;
                            Thread.Sleep(3000);
                        }
                    }
                }
                else
                {
                    QRBarCodePayMsg = "付款码支付失败！" + outputQRBarPayOutput.Message;
                    QRBarCodePayRes = -1;
                }
            }
            else
            {
                QRBarCodePayMsg = "获取流水号失败！";
                QRBarCodePayRes = -1;
            }
            if (this.Created)
            {
                this.BeginInvoke(this.invokeQRBarCodePay2);
            }
        }

        /// <summary>
        /// 更新QRBarCodePay2支付结果
        /// </summary>
        void updataQRBarCodePay2()
        {
            cmd.HideOpaqueLayer();
            //this.OutTradeNo.Text = DMFOutTradeNo;
            if (QRBarCodePayRes == 0)
            {
                //this.OutTradeNo.Text = DMFOutTradeNo;
                //string msg = "充值后余额：" + QRBarCodePayMsg;
                MessageBox.Show("医保电子凭证结算成功！");
                //textBoxcx.Text = "";
                this.textBoxPayAmount.Text = "0";
                this.textBoxPayAmount.ReadOnly = true;
                //this.OutTradeNo.Text = "";
                //textBoxFKM.Text = "";
                //textBoxcx.Focus();
            }
            else
            {
                MessageBox.Show(QRBarCodePayMsg);
                return;
            }
        }
        #endregion
        /// <summary>
        /// 打印凭证
        /// </summary>
        /// <param name="outTradeNo">订单号</param>
        /// <param name="amount">金额</param>
        /// <param name="payType">支付类型</param>
        public void PrintPt(string outTradeNo, decimal amount, string payType)
        {
            try
            {
                // 创建打印文档
                PrintDocument pd = new PrintDocument();
                pd.PrintPage += new PrintPageEventHandler((sender, e) =>
                {
                    // 设置打印内容
                    Font titleFont = new Font("宋体", 16, FontStyle.Bold);
                    Font normalFont = new Font("宋体", 12);
                    Font smallFont = new Font("宋体", 10);

                    float yPos = 50;
                    float leftMargin = e.MarginBounds.Left;
                    float centerX = e.PageBounds.Width / 2;

                    // 打印标题
                    e.Graphics.DrawString("门诊充值凭证", titleFont, Brushes.Black, centerX - 60, yPos);
                    yPos += 40;

                    // 打印订单信息
                    e.Graphics.DrawString("订单号: " + outTradeNo, normalFont, Brushes.Black, leftMargin, yPos);
                    yPos += 25;

                    e.Graphics.DrawString("充值金额: " + amount.ToString("F2") + "元", normalFont, Brushes.Black, leftMargin, yPos);
                    yPos += 25;

                    e.Graphics.DrawString("支付方式: " + payType, normalFont, Brushes.Black, leftMargin, yPos);
                    yPos += 25;

                    e.Graphics.DrawString("充值时间: " + getNowDateTime().ToString("yyyy-MM-dd HH:mm:ss"), normalFont, Brushes.Black, leftMargin, yPos);
                    yPos += 40;

                    // 打印提示信息
                    e.Graphics.DrawString("感谢您的使用！", smallFont, Brushes.Black, centerX - 50, yPos);
                });

                // 执行打印
                pd.Print();
            }
            catch (Exception ex)
            {
                MessageBox.Show("打印凭证失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 用户充值
        /// </summary>
        /// <param name="outTradeNo">订单号</param>
        /// <param name="amount">金额</param>
        /// <param name="paymentCode">付款码</param>
        /// <param name="payType">支付类型</param>
        /// <returns>充值结果</returns>
        public bool deposit_userDeposit(string outTradeNo, decimal amount, string paymentCode, string payType)
        {
            try
            {
                // 创建充值请求对象
                ServiceRef.DoPrepayIn inDoPrepay = new ServiceRef.DoPrepayIn();
                inDoPrepay.Amount = amount.ToString("F2");
                inDoPrepay.PatientID = patinfo.PatientID;
                inDoPrepay.PatientName = patinfo.PatientName;
                inDoPrepay.CardNO = patinfo.CardNO;
                inDoPrepay.TerminalCode = "001";
                
                // 调用充值服务
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                ServiceRef.DoPrepayOut outDoPrepay = clientService.DoPrepay(inDoPrepay);
                
                if (outDoPrepay != null && outDoPrepay.Result == "0")
                {
                    // 充值成功，更新患者信息
                    ServiceRef.HospitalService_XXXXClient clientService2 = new HospitalService_XXXXClient();
                    ServiceRef.QueryPatientInfoIn input = new ServiceRef.QueryPatientInfoIn();
                    input.QueryType = "1";
                    input.CardNO = patinfo.CardNO;
                    input.CardName = "";
                    if (patinfo.CardNO.Length > 15)
                        input.CardTypeID = "3";
                    else if (patinfo.CardNO.Length > 18)
                        input.CardTypeID = "4";
                    else
                        input.CardTypeID = "1";
                    input.TerminalCode = "001";
                    patinfo = clientService2.QueryPatientInfoCommon(input);
                    return true;
                }
                else
                {
                    MessageBox.Show("充值失败: " + (outDoPrepay?.Message ?? "未知错误"), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("充值异常: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 用户支付
        /// </summary>
        /// <param name="result">支付结果</param>
        /// <param name="amount">金额</param>
        /// <param name="paymentCode">付款码</param>
        /// <param name="outTradeNo">订单号</param>
        /// <returns>支付结果</returns>
        public bool pay_userPay(string result, decimal amount, string paymentCode, string outTradeNo)
        {
            try
            {
                // 创建支付请求对象
                ServiceRef.DoPayIn inDoPay = new ServiceRef.DoPayIn();
                inDoPay.PayAmount = amount.ToString("F2");
                inDoPay.PatientID = patinfo.PatientID;
                inDoPay.PatientName = patinfo.PatientName;
                inDoPay.CardNO = patinfo.CardNO;
                inDoPay.TerminalCode = "001";
                
                // 调用支付服务
                ServiceRef.HospitalService_XXXXClient clientService = new HospitalService_XXXXClient();
                ServiceRef.DoPayOut outDoPay = clientService.DoPay(inDoPay);
                
                if (outDoPay != null && outDoPay.Result == "0")
                {
                    // 支付成功，更新患者信息
                    ServiceRef.HospitalService_XXXXClient clientService2 = new HospitalService_XXXXClient();
                    ServiceRef.QueryPatientInfoIn input = new ServiceRef.QueryPatientInfoIn();
                    input.QueryType = "1";
                    input.CardNO = patinfo.CardNO;
                    input.CardName = "";
                    if (patinfo.CardNO.Length > 15)
                        input.CardTypeID = "3";
                    else if (patinfo.CardNO.Length > 18)
                        input.CardTypeID = "4";
                    else
                        input.CardTypeID = "1";
                    input.TerminalCode = "001";
                    patinfo = clientService2.QueryPatientInfoCommon(input);
                    return true;
                }
                else
                {
                    MessageBox.Show("支付处理失败: " + (outDoPay?.Message ?? "未知错误"), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("支付处理异常: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 根据申请单号查询医嘱名称
        /// </summary>
        /// <param name="applyNos">申请单号数组</param>
        /// <returns>医嘱名称查询结果</returns>
        public QueryOrderNameByApplyNoResponse QueryOrderNameByApplyNoList(string[] applyNos)
        {
            try
            {
                operateLog.WriteLog($"开始查询医嘱名称，申请单号数量: {applyNos?.Length ?? 0}");
                
                // 调用PatientDataService中的方法
                var result = PatientDataService.QueryOrderNameByApplyNoList(applyNos);
                
                if (result != null && result.Success == "1")
                {
                    operateLog.WriteLog($"查询医嘱名称成功，返回数据条数: {result.Data?.Length ?? 0}");
                }
                else
                {
                    operateLog.WriteLog($"查询医嘱名称失败: {result?.Message ?? "未知错误"}");
                }
                
                return result;
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"查询医嘱名称异常: {ex.Message}");
                return new QueryOrderNameByApplyNoResponse
                {
                    Success = "0",
                    Message = $"查询异常: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 根据申请单号查询医嘱名称（单个申请单号）
        /// </summary>
        /// <param name="applyNo">申请单号</param>
        /// <returns>医嘱名称查询结果</returns>
        public QueryOrderNameByApplyNoResponse QueryOrderNameByApplyNo(string applyNo)
        {
            if (string.IsNullOrWhiteSpace(applyNo))
            {
                return new QueryOrderNameByApplyNoResponse
                {
                    Success = "0",
                    Message = "申请单号不能为空",
                    Data = null
                };
            }

            return QueryOrderNameByApplyNoList(new string[] { applyNo });
        }

        /// <summary>
        /// 根据dgv_master中选中的申请单号批量查询医嘱名称
        /// </summary>
        /// <returns>医嘱名称查询结果</returns>
        public QueryOrderNameByApplyNoResponse QuerySelectedOrderNames()
        {
            try
            {
                List<string> selectedApplyNos = new List<string>();
                
                // 遍历dgv_master获取选中的申请单号
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    if (row.Cells["ColumnSelect"].Value != null && 
                        Convert.ToBoolean(row.Cells["ColumnSelect"].Value) == true)
                    {
                        string applyNo = row.Cells["apply_master"]?.Value?.ToString();
                        if (!string.IsNullOrWhiteSpace(applyNo))
                        {
                            selectedApplyNos.Add(applyNo);
                        }
                    }
                }
                
                if (selectedApplyNos.Count == 0)
                {
                    return new QueryOrderNameByApplyNoResponse
                    {
                        Success = "0",
                        Message = "未选中任何申请单",
                        Data = null
                    };
                }
                
                operateLog.WriteLog($"批量查询医嘱名称，选中申请单数量: {selectedApplyNos.Count}");
                
                return QueryOrderNameByApplyNoList(selectedApplyNos.ToArray());
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"批量查询医嘱名称异常: {ex.Message}");
                return new QueryOrderNameByApplyNoResponse
                {
                    Success = "0",
                    Message = $"查询异常: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 异步查询医嘱名称并填入dgv_master的OrderName字段
        /// </summary>
        private void AsyncQueryAndFillOrderNames()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    // 收集dgv_master中所有apply_master列的内容
                    List<string> applyNos = new List<string>();
                    
                    // 在UI线程中收集数据
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new Action(() =>
                        {
                            foreach (DataGridViewRow row in dgv_master.Rows)
                            {
                                if (row.Cells["apply_master"].Value != null)
                                {
                                    string applyNo = row.Cells["apply_master"].Value.ToString().Trim();
                                    if (!string.IsNullOrEmpty(applyNo) && !applyNos.Contains(applyNo))
                                    {
                                        applyNos.Add(applyNo);
                                    }
                                }
                            }
                        }));
                    }
                    else
                    {
                        foreach (DataGridViewRow row in dgv_master.Rows)
                        {
                            if (row.Cells["apply_master"].Value != null)
                            {
                                string applyNo = row.Cells["apply_master"].Value.ToString().Trim();
                                if (!string.IsNullOrEmpty(applyNo) && !applyNos.Contains(applyNo))
                                {
                                    applyNos.Add(applyNo);
                                }
                            }
                        }
                    }
                    
                    if (applyNos.Count == 0)
                    {
                        operateLog.WriteLog("未找到有效的申请单号，跳过医嘱名称查询");
                        return;
                    }
                    
                    operateLog.WriteLog($"开始异步查询{applyNos.Count}个申请单号的医嘱名称");
                    
                    // 调用查询医嘱名称接口
                    var response = PatientDataService.QueryOrderNameByApplyNoList(applyNos.ToArray());
                    
                    if (response != null && response.Success == "1" && response.Data != null && response.Data.Length > 0)
                    {
                        operateLog.WriteLog($"成功查询到{response.Data.Length}条医嘱名称数据");
                        
                        // 在UI线程中更新dgv_master的OrderName字段
                        if (this.InvokeRequired)
                        {
                            this.Invoke(new Action(() => UpdateOrderNamesInGrid(response.Data)));
                        }
                        else
                        {
                            UpdateOrderNamesInGrid(response.Data);
                        }
                    }
                    else
                    {
                        string errorMsg = response?.Message ?? "未知错误";
                        operateLog.WriteLog($"查询医嘱名称失败: {errorMsg}");
                    }
                }
                catch (Exception ex)
                {
                    operateLog.WriteLog($"异步查询医嘱名称异常: {ex.Message}");
                }
            });
        }
        #region 自费执行
        /// <summary>
        /// 设置execPay按钮的显示状态
        /// </summary>
        /// <param name="row">DataGridView行</param>
        /// <param name="visible">是否显示按钮</param>
        private void SetExecPayButtonVisibility(DataGridViewRow row, bool visible)
        {
            if (visible)
            {
                // 显示按钮
                row.Cells["execPay"].Value = "执行收费";
                row.Cells["execPay"].ReadOnly = false;
                row.Cells["execPay"].Style.ForeColor = System.Drawing.Color.Black;
                row.Cells["execPay"].Style.BackColor = System.Drawing.SystemColors.Control;
            }
            else
            {
                // 隐藏按钮并完全禁用
                row.Cells["execPay"].Value = "";
                row.Cells["execPay"].ReadOnly = true;
                row.Cells["execPay"].Style.ForeColor = System.Drawing.Color.Transparent;
                row.Cells["execPay"].Style.BackColor = System.Drawing.Color.Transparent;
                // 额外设置选择背景色为透明，确保完全不可见
                row.Cells["execPay"].Style.SelectionForeColor = System.Drawing.Color.Transparent;
                row.Cells["execPay"].Style.SelectionBackColor = System.Drawing.Color.Transparent;
            }
        }

        /// <summary>
        /// 更新dgv_master中的医嘱名称数据
        /// </summary>
        /// <param name="orderNameData">医嘱名称数据数组</param>
        private void UpdateOrderNamesInGrid(OrderNameData[] orderNameData)
        {
            try
            {
                if (orderNameData == null || orderNameData.Length == 0)
                {
                    operateLog.WriteLog("医嘱名称数据为空，无法更新");
                    return;
                }
                
                // 创建申请单号到医嘱名称和建议金额的映射字典
                Dictionary<string, string> applyNoToOrderName = new Dictionary<string, string>();
                Dictionary<string, string> applyNoToSuggestedAmount = new Dictionary<string, string>();
                foreach (var item in orderNameData)
                {
                    if (!string.IsNullOrEmpty(item.ApplyNo) && !string.IsNullOrEmpty(item.OrderNames))
                    {
                        applyNoToOrderName[item.ApplyNo.Trim()] = item.OrderNames.Trim();
                        
                        // 同时保存建议金额，如果为空则保持原有金额
                        if (!string.IsNullOrEmpty(item.Suggested_Amount))
                        {
                            applyNoToSuggestedAmount[item.ApplyNo.Trim()] = item.Suggested_Amount.Trim();
                        }
                    }
                }
                
                int updatedCount = 0;
                
                // 遍历dgv_master的每一行，通过apply_master匹配并填入OrderName
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    if (row.Cells["apply_master"].Value != null)
                    {
                        string applyMaster = row.Cells["apply_master"].Value.ToString().Trim();
                        
                        if (applyNoToOrderName.ContainsKey(applyMaster))
                        {
                            // 找到匹配的申请单号，填入医嘱名称
                            string orderName = applyNoToOrderName[applyMaster];
                            row.Cells["OrderName"].Value = orderName;
                            
                            // 如果有建议金额，则更新金额列
                            if (applyNoToSuggestedAmount.ContainsKey(applyMaster))
                            {
                                string suggestedAmount = applyNoToSuggestedAmount[applyMaster];
                                
                                // 获取原来的金额值
                                string originalAmount = row.Cells["金额"].Value?.ToString() ?? "";
                                
                                // 判断是否需要更新：如果原金额不为零而建议金额为零，则不替换
                                bool shouldUpdate = true;
                                if (!string.IsNullOrEmpty(originalAmount) && originalAmount != "0" && originalAmount != "0.00")
                                {
                                    if (string.IsNullOrEmpty(suggestedAmount) || suggestedAmount == "0" || suggestedAmount == "0.00")
                                    {
                                        shouldUpdate = false;
                                        operateLog.WriteLog($"申请单号 {applyMaster} 保留原金额 {originalAmount}，不使用零值建议金额");
                                    }
                                }
                                
                                if (shouldUpdate)
                                {
                                    row.Cells["金额"].Value = suggestedAmount;
                                    operateLog.WriteLog($"申请单号 {applyMaster} 的金额已更新为建议金额: {suggestedAmount}");
                                }
                            }
                            
                            // 控制execPay按钮的显示：只有当医嘱名称包含"诊查费"时才显示按钮
                            SetExecPayButtonVisibility(row, orderName.Contains("诊查费"));
                            
                            updatedCount++;
                        }
                        else
                        {
                            // 没有匹配到医嘱名称的行，隐藏execPay按钮
                            SetExecPayButtonVisibility(row, false);
                        }
                    }
                    else
                    {
                        // apply_master为空的行，隐藏execPay按钮
                        SetExecPayButtonVisibility(row, false);
                    }
                }
                
                operateLog.WriteLog($"成功更新{updatedCount}行的医嘱名称数据");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog($"更新医嘱名称数据异常: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 折叠按钮点击事件处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnToggleLocalData_Click(object sender, EventArgs e)
        {
            // [折叠功能暂时禁用] 点击折叠按钮不执行任何操作
            // ToggleLocalDataCollapse();
        }
        
        /// <summary>
        /// 切换dgvLocalData的折叠状态
        /// </summary>
        private void ToggleLocalDataCollapse()
        {
            // [折叠功能暂时禁用] 折叠/展开逻辑已停用，避免控件位置和尺寸变化。
            // 原始实现已注释，不再执行任何UI位置调整。
            return;
        }

        /// <summary>
        /// 重置dgv_master所有行的复选框状态为未勾选，包括表头复选框
        /// </summary>
        private void ResetAllCheckBoxes()
        {
            try
            {
                // 重置表头复选框状态
                if (ColumnSelect.HeaderCell is DatagridViewCheckBoxHeaderCell headerCell)
                {
                    headerCell.Checked = false;
                    dgv_master.InvalidateColumn(ColumnSelect.Index); // 刷新列显示
                }
                
                // 重置所有行的复选框状态
                foreach (DataGridViewRow row in dgv_master.Rows)
                {
                    if (!row.IsNewRow)
                    {
                        row.Cells["ColumnSelect"].Value = false;
                    }
                }
                operateLog.WriteLog("已重置所有复选框状态为未勾选，包括表头复选框");
            }
            catch (Exception ex)
            {
                operateLog.WriteLog("重置复选框状态异常：" + ex.Message);
            }
        }
        
        #endregion
        
        #region JSON日志记录功能
        
        /// <summary>
        /// 将DoWork方法的结果（patinfo、PayDetail、payDetailList）生成JSON并写入日志
        /// 可通过App.config中的EnableDoWorkJsonLogging配置项控制是否启用此功能
        /// </summary>
        /// <param name="cardNo">输入的卡号</param>
        /// <param name="patientInfo">患者信息</param>
        /// <param name="payDetail">支付详情字典</param>
        /// <param name="payDetailList">支付详情列表</param>
        private void LogDoWorkResultToJson(string cardNo, ServiceRef.QueryPatientInfoOut patientInfo, 
            Dictionary<string, ServiceRef.QueryToPayRecipeDetailInfoOut[]> payDetail, 
            List<ServiceRef.BMS_ORDERS_BILL_DETAILChargeItemItem> payDetailList)
        {
            try
            {
                // 检查配置是否启用JSON日志记录功能
                string enableLogging = ConfigurationManager.AppSettings["EnableDoWorkJsonLogging"];
                if (string.IsNullOrEmpty(enableLogging) || enableLogging.ToLower() != "true")
                {
                    // 功能未启用，直接返回
                    return;
                }
                
                // 创建JSON对象
                var jsonData = new
                {
                    timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    cardNo = cardNo ?? "",
                    operatorInfo = new
                    {
                        userId = userData?.user_id ?? "",
                        userName = userData?.user_name ?? ""
                    },
                    patientInfo = patientInfo == null ? null : new
                    {
                        PatientID = patientInfo.PatientID ?? "",
                        PatientName = patientInfo.PatientName ?? "",
                        PatientSex = patientInfo.PatientSex ?? "",
                        PatientAge = patientInfo.PatientAge ?? "",
                        CardNO = patientInfo.CardNO ?? "",
                        Balance = patientInfo.Balance ?? "",
                        PatientBirthday = patientInfo.PatientBirthday ?? "",
                        PatientIDCardNO = patientInfo.PatientIDCardNO ?? "",
                        PatientTelephone = patientInfo.PatientTelephone ?? "",
                        MedicareNO = patientInfo.MedicareNO ?? ""
                    },
                    payDetail = payDetail == null ? null : payDetail.ToDictionary(
                        kvp => kvp.Key,
                        kvp => kvp.Value?.Select(item => new
                        {
                            // 只使用QueryToPayRecipeDetailInfoOut类中实际存在的属性
                            Amount = item?.Amount ?? "",
                            ApplyClass = item?.ApplyClass ?? "",
                            ApplyClassName = item?.ApplyClassName ?? "",
                            ApplyId = item?.ApplyId ?? "",
                            AutoRatio = item?.AutoRatio ?? "",
                            ChargeDate = item?.ChargeDate ?? "",
                            ChargedStatus = item?.ChargedStatus ?? "",
                            Charges = item?.Charges ?? "",
                            ClinicId = item?.ClinicId ?? "",
                            ClinicItemCode = item?.ClinicItemCode ?? "",
                            Costs = item?.Costs ?? "",
                            CurrentNursingUnit = item?.CurrentNursingUnit ?? "",
                            DiagByCode = item?.DiagByCode ?? "",
                            DiagEmpId = item?.DiagEmpId ?? "",
                            DiagEmpName = item?.DiagEmpName ?? "",
                            DiagIcd = item?.DiagIcd ?? "",
                            DiagName = item?.DiagName ?? "",
                            Diags = item?.Diags ?? "",
                            DoctName = item?.DoctName ?? "",
                            DoctCode = item?.DoctCode ?? "",
                            Duration = item?.Duration ?? "",
                            DurationUnitName = item?.DurationUnitName ?? "",
                            EnterDate = item?.EnterDate ?? "",
                            ExternalId = item?.ExternalId ?? "",
                            Factor = item?.Factor ?? "",
                            FreqName = item?.FreqName ?? "",
                            FreqUnitName = item?.FreqUnitName ?? "",
                            InClassOnRcptCode = item?.InClassOnRcptCode ?? "",
                            InClassOnRcptCodeName = item?.InClassOnRcptCodeName ?? "",
                            InOutFlag = item?.InOutFlag ?? "",
                            InsurLevelCode = item?.InsurLevelCode ?? "",
                            InsurLevelName = item?.InsurLevelName ?? "",
                            InsuranceType = item?.InsuranceType ?? "",
                            InvoicePrintStatus = item?.InvoicePrintStatus ?? "",
                            IsCharge = item?.IsCharge ?? "",
                            ItemClass = item?.ItemClass ?? "",
                            ItemClassName = item?.ItemClassName ?? "",
                            ItemCode = item?.ItemCode ?? "",
                            ItemId = item?.ItemId ?? "",
                            ItemName = item?.ItemName ?? "",
                            MedUnitName = item?.MedUnitName ?? "",
                            OrderBeginDate = item?.OrderBeginDate ?? "",
                            OrderByDeptCode = item?.OrderByDeptCode ?? "",
                            OrderByDeptName = item?.OrderByDeptName ?? "",
                            OrderDate = item?.OrderDate ?? "",
                            OrderId = item?.OrderId ?? "",
                            OrderItemDetailId = item?.OrderItemDetailId ?? "",
                            OrgIdHospital = item?.OrgIdHospital ?? "",
                            OutClassOnRcptCode = item?.OutClassOnRcptCode ?? "",
                            OutClassOnRcptCodeName = item?.OutClassOnRcptCodeName ?? "",
                            PatientId = item?.PatientId ?? "",
                            PerMed = item?.PerMed ?? "",
                            PerformedByDeptCode = item?.PerformedByDeptCode ?? "",
                            PerformedByDeptName = item?.PerformedByDeptName ?? "",
                            Price = item?.Price ?? "",
                            Quantity = item?.Quantity ?? "",
                            Ratio = item?.Ratio ?? "",
                            RecipeNO = item?.RecipeNO ?? "",
                            Remark = item?.Remark ?? "",
                            RetailFactor = item?.RetailFactor ?? "",
                            SalesPrice = item?.SalesPrice ?? ""
                        }).ToArray()
                    ),
                    payDetailList = payDetailList?.Select(item => new
                    {
                        Amount = item?.Amount ?? "",
                        ApplyClass = item?.ApplyClass ?? "",
                        ApplyClassName = item?.ApplyClassName ?? "",
                        ApplyId = item?.ApplyId ?? "",
                        AutoRatio = item?.AutoRatio ?? "",
                        ChargeDate = item?.ChargeDate ?? "",
                        ChargedStatus = item?.ChargedStatus ?? "",
                        Charges = item?.Charges ?? "",
                        ClinicId = item?.ClinicId ?? "",
                        ClinicItemCode = item?.ClinicItemCode ?? "",
                        Costs = item?.Costs ?? "",
                        CurrentNursingUnit = item?.CurrentNursingUnit ?? "",
                        DiagByCode = item?.DiagByCode ?? "",
                        DiagEmpId = item?.DiagEmpId ?? "",
                        DiagEmpName = item?.DiagEmpName ?? "",
                        DiagIcd = item?.DiagIcd ?? "",
                        DiagName = item?.DiagName ?? "",
                        Diags = item?.Diags ?? "",
                        Duration = item?.Duration ?? "",
                        DurationUnitName = item?.DurationUnitName ?? "",
                        EnterDate = item?.EnterDate ?? "",
                        ExternalId = item?.ExternalId ?? "",
                        Factor = item?.Factor ?? "",
                        FreqName = item?.FreqName ?? "",
                        FreqUnitName = item?.FreqUnitName ?? "",
                        InClassOnRcptCode = item?.InClassOnRcptCode ?? "",
                        InClassOnRcptCodeName = item?.InClassOnRcptCodeName ?? "",
                        InOutFlag = item?.InOutFlag ?? "",
                        InsurLevelCode = item?.InsurLevelCode ?? "",
                        InsurLevelName = item?.InsurLevelName ?? "",
                        InsuranceType = item?.InsuranceType ?? "",
                        InvoicePrintStatus = item?.InvoicePrintStatus ?? "",
                        IsCharge = item?.IsCharge ?? "",
                        ItemClass = item?.ItemClass ?? "",
                        ItemClassName = item?.ItemClassName ?? "",
                        ItemCode = item?.ItemCode ?? "",
                        ItemId = item?.ItemId ?? "",
                        ItemName = item?.ItemName ?? "",
                        MedUnitName = item?.MedUnitName ?? "",
                        OrderBeginDate = item?.OrderBeginDate ?? "",
                        OrderByDeptCode = item?.OrderByDeptCode ?? "",
                        OrderByDeptName = item?.OrderByDeptName ?? "",
                        OrderDate = item?.OrderDate ?? "",
                        OrderId = item?.OrderId ?? "",
                        OrderItemDetailId = item?.OrderItemDetailId ?? "",
                        OrgIdHospital = item?.OrgIdHospital ?? "",
                        OutClassOnRcptCode = item?.OutClassOnRcptCode ?? "",
                        OutClassOnRcptCodeName = item?.OutClassOnRcptCodeName ?? "",
                        PatientId = item?.PatientId ?? "",
                        PatientVisitId = item?.PatientVisitId ?? "",
                        PerMed = item?.PerMed ?? "",
                        PerformedByDeptCode = item?.PerformedByDeptCode ?? "",
                        PerformedByDeptName = item?.PerformedByDeptName ?? "",
                        Price = item?.Price ?? "",
                        Quantity = item?.Quantity ?? "",
                        Ratio = item?.Ratio ?? "",
                        RetailFactor = item?.RetailFactor ?? "",
                        SalesPrice = item?.SalesPrice ?? ""
                    }).ToArray()
                };
                
                // 使用JavaScriptSerializer转换为JSON字符串
                System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                string jsonString = serializer.Serialize(jsonData);
                
                // 写入日志
                operateLog.WriteLog("=== DoWork结果JSON数据开始 ===");
                operateLog.WriteLog(jsonString);
                operateLog.WriteLog("=== DoWork结果JSON数据结束 ===");
            }
            catch (Exception ex)
            {
                // JSON日志记录失败不应影响主要业务流程，只记录错误日志
                operateLog.WriteLog("JSON日志记录异常：" + ex.Message);
            }
        }
        
        #endregion
    }
}
